Skip to content

sync: merge upstream/master into master / 同步上游 upstream/master 到 master - #19

Merged
aistackdev merged 106 commits into
masterfrom
sync/upstream-20260814
Aug 14, 2026
Merged

sync: merge upstream/master into master / 同步上游 upstream/master 到 master#19
aistackdev merged 106 commits into
masterfrom
sync/upstream-20260814

Conversation

@aistackdev

Copy link
Copy Markdown

Summary

Merges upstream (SemiAnalysisAI/InferenceX-app) through a8c9e154 into master. Resolved 3 real conflicts additively per fork-changelog (both sides' entries kept, no upstream content dropped):

同步上游仓库 (SemiAnalysisAI/InferenceX-app) 至 a8c9e154。按照 fork-changelog 以叠加方式解决了 3 处真实冲突(双方条目均保留,未丢弃上游内容):

  • packages/constants/src/gpu-keys.ts — kept both rtx6000pro (upstream) and rtx5090 (fork-only), renumbered sort to avoid a collision (9/10).
  • packages/app/src/lib/compare-slug.ts — kept both kimi-k3 (upstream) and deepseek-coder-v2-lite (fork-only) entries.
  • packages/app/src/lib/compare-slug.test.ts — kept both expected-name rows.

Also required bun install (upstream switched package manager to bun@1.3.14, pnpm install no longer works) before the pre-commit typecheck hook would pass.

Test plan

  • Verified all fork-changelog entries survived: GITHUB_REPOS includes vngcloud/InferenceX, dsv2lite registered across models.ts/normalizers.ts/data-mappings.ts/compare-ssr.ts/compare-slug.ts, rtx5090 in HW_REGISTRY.
  • Lefthook pre-commit (format/lint/typecheck) passed on the merge commit after bun install.
  • CI green on this PR

🤖 Generated with Claude Code

Oseltamivir and others added 30 commits July 24, 2026 01:50
…nalysisAI#621)

* fix(overview): clarify cross-platform result coverage

Add engine scope selection and select each platform independently using speculative FP4 → speculative FP8 → standard FP4 → standard FP8. Represent the page as one ordered platform matrix, normalize only disaggregated throughput across all deployed prefill and decode GPUs, and mark true between-run estimates with ≈ while preserving localized evidence links.

中文:增加引擎范围筛选,并按照推测解码 FP4 → 推测解码 FP8 → 标准解码 FP4 → 标准解码 FP8 的顺序独立选择各平台结果。将页面数据收敛为统一的平台矩阵,仅对分离式推理按全部预填充与解码 GPU 归一化吞吐量;运行点之间的估算值以 ≈ 标记,并保留本地化证据链接。

* feat(overview): show cost per Mtok with color-graded B200 deltas, default to community engines

* refactor(overview): continuous cost-delta shade ramp with neutral band

* fix(overview): label B200 as cost baseline and stop badge/date overlap

* feat(overview): reference-column layout, compressed copy, mobile two-tier cards

* fix(overview): stop cost text overlapping delta badge in narrow desktop columns
…miAnalysisAI#622)

* fix(overview): restore full engine scope labels

* fix(overview): move evidence date into metadata row so the matrix fits without clipping

* fix(overview): compress cell spacing so the full matrix fits at 1280px

* fix(overview): loosen row spacing and de-emphasize cell metadata

* fix(overview): improve configuration metadata readability

Increase configuration metadata from 10px to 11px while preserving its subdued visual hierarchy. Add an E2E regression assertion for the rendered font size.

中文:将配置元数据字号从 10px 提升到 11px,同时保持弱化的信息层级;新增 E2E 回归断言验证实际渲染字号。

* fix(overview): simplify phone comparison layout

Render platforms as compact aligned rows below 640px while preserving the two-plus-three tablet grouping and the desktop matrix. Add responsive geometry coverage for 320px, 390px, and 768px viewports.

中文:在 640px 以下将平台结果渲染为紧凑对齐行,同时保留平板端的两加三分组和桌面矩阵;新增 320px、390px 与 768px 的响应式几何回归测试。

* fix(overview): unify phone and tablet comparison rows

Use the same five-row platform layout below the desktop breakpoint and keep cost deltas beside their values with typographic baseline alignment. Add responsive regression coverage across phone and tablet widths.

中文:统一总览页手机和平板的五行平台布局,并将成本差值紧邻数值、按文字基线对齐。补充覆盖手机和平板宽度的响应式回归测试。
…AnalysisAI#627)

Replace the 9.99 placeholders in HW_REGISTRY with the official values
from the SemiAnalysis AI Cloud TCO model:

- All-in power: 0.975 kW/GPU
- Owning - Hyperscaler (costh): $0.43/GPU/hr
- Owning - Neocloud Giant (costn): $0.676/GPU/hr
- 3 Year Rental (costr): $0.52/GPU/hr

$/token and per-MW metrics for this SKU are now meaningful.

中文:将 HW_REGISTRY 中 RTX PRO 6000 的 9.99 占位值替换为 SemiAnalysis
AI Cloud TCO 模型的正式数值:整机功耗 0.975 kW/GPU;自有 - Hyperscaler
$0.43/GPU/hr;自有 - Neocloud Giant $0.676/GPU/hr;3 年租赁 $0.52/GPU/hr。
该 SKU 的 $/token 与每 MW 指标自此有效。

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* chore: bump workspace dependencies and security pins

中文:更新工作区依赖与安全版本约束

* chore: clarify security pins and test names

中文:澄清安全版本约束与测试名称

* chore: use cross-env for unit tests

* chore: clarify reload test setup

* test: assert chunk listener installation

* test: isolate local storage setup

* test: harden chunk recovery assertions
* ci: remove workflow cache warnings

* ci: serialize pnpm cache writes

* ci: prevent Cypress cache races
…emiAnalysisAI#630)

* chore: migrate workspace tooling to bun

中文:将工作区工具链迁移至 Bun,并同步更新 CI、脚本、依赖锁文件和开发文档。

* fix: bound Bun JSON decompression memory

中文:限制 Bun JSON 解压缩的内存占用,并对大型指标产物使用流式解析。
…/ 在 TCO 计算器中显示非官方运行叠加数据 (SemiAnalysisAI#631)

* feat(calculator): show unofficial-run overlays in the TCO calculator

A run loaded via `?unofficialrun=<id>` now contributes an extra bar per
(hardware × run) to the calculator's bar chart, in the run's palette color and
labeled `B300 (✕ my-branch)`, so the throughput / cost / tok-s-MW delta a branch
produces at a target interactivity is readable without leaving the tab.

Overlay results are interpolated separately from official ones — folding them
into the official Pareto frontier would silently move the official numbers and
hide the before/after delta. Both paths share one row → GPUDataPoint mapper
(`buildGpuGroups`) so an overlay bar and its official twin can't drift apart.

Only the bar chart and its legend consume overlay data. The table view, CSV
export, and fleet planner stay official-only: an exported sheet or an MW
projection that blends in numbers from an unmerged branch is worse than one
that omits them.

中文:在 TCO 计算器中支持非官方运行(unofficial run)叠加显示。

通过 `?unofficialrun=<id>` 加载运行后,柱状图会为每个(硬件 × 运行)组合额外
绘制一根柱子,使用该运行的调色板颜色,并标注为 `B300 (✕ my-branch)`,从而无需
离开该标签页即可读出分支在目标交互性下带来的吞吐量 / 成本 / tok/s/MW 差异。

要点:
- 叠加数据独立插值,不并入官方 Pareto 前沿——否则官方数值会被悄然改变,
  且看不出改动前后的差异;两条路径共用同一个 row → GPUDataPoint 映射函数
  (`buildGpuGroups`),确保叠加柱与其官方对应柱不会因映射漂移而不一致。
- 仅图表与图例消费叠加数据;表格视图、CSV 导出和 Fleet Planner 保持仅官方数据,
  避免导出的表格或兆瓦(MW)规划中混入未合并分支的数值。
- 图例合并了仅存在于该运行中的硬件,切换硬件会同步到共享的
  `activeOverlayHwTypes`,一次点击即可同时隐藏该 GPU 的官方柱与叠加柱。

* fix(calculator): make one legend the sole owner of overlay visibility

Addresses both Bugbot findings, which share a root cause: overlay bars were
gated on the provider's shared `activeOverlayHwTypes` while official bars were
gated on the local `visibleHwKeys`. Two backing sets behind one legend can only
drift, and every way they drift renders a legend entry that contradicts the bar
beside it:

- the reset effect reseeds `visibleHwKeys` when the available hardware changes
  but (rightly) does not reseed a set two other tabs share, so a GPU hidden
  before a model/sequence switch came back "active" in the legend with its
  overlay bar still hidden;
- the inference or evaluation tab re-enabling a GPU resurrected its calculator
  overlay bar while this tab's legend still marked it inactive.

`visibleHwKeys` is now the single source of truth for both series, and the
mirror into the shared set is gone. Per-tab hardware visibility is already how
the calculator treats official data, so the overlay series just follows the same
rule.

Adds a regression e2e case that fails on the previous commit: hide a GPU, switch
sequence and back, expect every bar to return.

中文:让单一图例成为叠加可见性的唯一来源。

修复 Bugbot 报告的两个问题,二者根因相同:叠加柱由 Provider 共享的
`activeOverlayHwTypes` 控制,而官方柱由本地的 `visibleHwKeys` 控制。同一个图例
背后存在两套状态集合,必然会不同步,且每种不同步都会导致图例条目的状态与旁边的
柱子自相矛盾:

- 可用硬件变化时,重置逻辑会重新填充 `visibleHwKeys`,但(合理地)不会重置由
  另外两个标签页共享的集合。因此在切换模型/序列前隐藏的 GPU,切换后在图例中
  重新显示为激活状态,其叠加柱却仍被此前的筛选隐藏;
- 在推理或评估标签页重新启用某个 GPU,会让计算器中对应的叠加柱重新出现,而本
  标签页的图例仍将其标记为未激活。

现在 `visibleHwKeys` 是两个系列的唯一真实来源,已移除向共享集合的同步写入。
按标签页隔离硬件可见性本就是计算器处理官方数据的方式,叠加系列沿用同一规则。

新增一个回归 e2e 用例(在上一个提交上会失败):隐藏某个 GPU,切换序列后再切回,
断言所有柱子都恢复显示。

* fix(calculator): escape untrusted tooltip text, disclose clamped values

Two findings from the second Bugbot pass.

Escaping: the bar tooltip is built as an HTML string and injected with .html().
Overlay branch names and run URLs come from the GitHub API for whatever run id
the user pasted into `?unofficialrun=`, and git permits `<` and `>` in a ref
name, so a crafted branch could inject markup on hover. Adds `escapeHtml` in
lib/utils and applies it to every value in that tooltip that this codebase did
not author.

Clamping: `interpolateForGPU` clamps the target into each series' own range and
always returns a value, so a bar can show its nearest edge point as if it were
measured at the current target. That was already possible across GPUs with
different ranges; widening the slider to cover overlay operating points makes it
reachable for every official bar at once, which turns a side-by-side overlay
delta into a real-vs-clamped comparison. Rather than narrow the slider (which
only moves the clamping onto the overlay bars, and breaks the case where a model
exists only in the run), the result now carries a `clamped` flag and the tooltip
says so.

中文:转义 tooltip 中的不可信文本,并标注被钳制(clamped)的数值。

修复 Bugbot 第二轮审查提出的两个问题。

转义:柱状图 tooltip 以 HTML 字符串构建并通过 .html() 注入。叠加运行的分支名和
运行 URL 来自 GitHub API(对应用户在 `?unofficialrun=` 中粘贴的任意运行 ID),
而 git 允许分支名包含 `<` 和 `>`,因此精心构造的分支名可在悬停时注入标记。现在
在 lib/utils 中新增 `escapeHtml`,并将其应用于该 tooltip 中所有非本代码库生成
的值。

钳制:`interpolateForGPU` 会把目标值钳制到各序列自身的范围内并始终返回结果,
因此柱子可能展示其最近的边缘数据点,却看起来像是在当前目标下实测所得。这在不同
量程的 GPU 之间本就可能发生;而将滑块范围扩展到覆盖叠加数据的工作点后,所有官方
柱子可能同时进入该状态,使并排的叠加对比变成"实测值 vs 钳制值"的比较。相比收窄
滑块范围(那只会把钳制转移到叠加柱上,并且会破坏"模型仅存在于该运行中"的场景),
现在结果携带 `clamped` 标志,并在 tooltip 中明确提示。

* fix(calculator): keep GPU filters across overlay arrival, exempt run legend rows

Two findings from the third Bugbot pass.

Filter wipe: the legend reset effect keyed on the merged official+overlay
hardware list. An unofficial run is fetched separately and usually resolves
after the benchmarks, so when it landed and added overlay-only hardware the
effect reseeded and wiped GPU filters the user had already set. The reset now
keys on the official list only — reseeding on a user-driven model/sequence/
precision change is intentional, reseeding on async overlay arrival is not — and
overlay hardware appearing or leaving is applied additively, with a guard so
dismissing a run can't leave an empty chart.

Legend guard: unofficial-run legend entries are labels, not series — always
active, with nothing to remove. They were inflating ChartLegend's active count,
which is what stops the hide control emptying the chart, so a user could remove
the last real GPU; and the hide control on a run entry called removeGpu with an
`overlay-run-*` key and did nothing. Adds an opt-out (`isRemovable`, default
true, so no other tab changes) and sets it on those entries.

中文:叠加数据到达时保留 GPU 筛选,并将运行图例条目排除在移除逻辑之外。

修复 Bugbot 第三轮审查提出的两个问题。

筛选被清空:图例重置逻辑此前基于"官方 + 叠加"合并后的硬件列表。非官方运行是
单独拉取的,通常在基准数据之后才返回,因此当它带来仅存在于叠加数据中的硬件时,
重置逻辑会重新填充并清空用户已设置的 GPU 筛选。现在重置仅基于官方列表——用户
主动切换模型/序列/精度时重置是符合预期的,而因叠加数据异步到达而重置则不是;
叠加硬件的出现与消失改为增量应用,并加入保护逻辑,确保移除运行后图表不会变空。

图例保护:非官方运行的图例条目是标签而非数据系列——始终处于激活状态,也没有可
移除的内容。它们此前会虚增 ChartLegend 的激活计数(该计数用于防止隐藏控件把图表
清空),导致用户可以移除最后一个真实 GPU;而点击运行条目上的隐藏控件会以
`overlay-run-*` 键调用 removeGpu,实际不产生任何效果。现在新增 `isRemovable`
选项(默认 true,因此其他标签页行为不变),并在这些条目上设为 false。

* fix(calculator): clear stale hardware when a selection has no official data

Fourth Bugbot pass. The legend reset effect bailed out whenever the official
hardware list was empty, treating "no official data for this selection" as
"still loading". But an empty official list is a real state — it is exactly the
"this model/sequence exists only in the unofficial run" case this feature is
for. The previous selection's official keys stayed in `visibleHwKeys` and
`prevAvailableKeyRef` went un-updated, so the solo/show-all arithmetic in
`toggleGpuVisibility` counted hardware that isn't on the chart and a hide click
removed a GPU instead of soloing it.

The guard now tests the merged list (nothing to seed from at all) while the
change detection still keys on the official list, so late overlay arrival still
does not wipe filters. `toggleGpuVisibility` additionally counts visible keys
against the legend rather than the raw set size, so no stale entry can skew it
again.

中文:当某个选择没有官方数据时,清除残留的硬件选中状态。

Bugbot 第四轮审查。图例重置逻辑此前在官方硬件列表为空时直接返回,把"该选择没有
官方数据"当成了"仍在加载"。但官方列表为空是一个真实状态——正是本功能所针对的
"该模型/序列仅存在于非官方运行中"的场景。上一次选择的官方键会残留在
`visibleHwKeys` 中,`prevAvailableKeyRef` 也不会更新,导致 `toggleGpuVisibility`
中的 solo / 显示全部逻辑把图表上并不存在的硬件计算在内,点击隐藏时变成移除某个
GPU 而非将其单独显示。

现在守卫条件改为检查合并后的列表(即完全没有可用于初始化的数据),而变更检测仍
基于官方列表,因此叠加数据延迟到达时依然不会清空筛选。此外,
`toggleGpuVisibility` 改为对照图例统计可见键,而不是使用集合本身的大小,避免任何
残留条目再次干扰该逻辑。

* docs(calculator): record the overlay behavior added during review

The overlay section was written against the first design and never caught up
with the fixes that followed: legend seeding (reset keyed on the official list,
overlay applied additively, and why the early-out guards the merged list),
`isRemovable` on run legend entries, the `clamped` tooltip disclosure, and
tooltip escaping.

中文:补充审查过程中新增的叠加显示行为文档。

叠加显示章节此前基于最初的设计撰写,未同步后续修复内容:图例初始化(重置基于
官方列表、叠加数据增量应用,以及提前返回为何要检查合并后的列表)、运行图例条目
上的 `isRemovable`、tooltip 中的 `clamped` 提示,以及 tooltip 转义。

* fix(calculator): don't blank the chart on an overlay-only selection

Fifth Bugbot pass. The additive overlay effect's "never strand an empty chart"
fallback reached for the official hardware list — which is empty precisely on an
overlay-only selection, so it produced an empty set and filtered out overlay
bars that still had data. The official-list reset could not recover it either,
because that list stays empty across the change and so never reseeds. The
fallback now reaches for everything that still has data, official and overlay.

The reset key is also no longer the official hardware list alone. It is now the
user's actual selection (model, sequence, precisions, run date) plus that list,
so an overlay-only model or sequence change reseeds like any other selection
change, while a late run arrival — which changes none of those — still does not
wipe the user's filters.

中文:在仅有叠加数据的选择下不要清空图表。

Bugbot 第五轮审查。增量叠加逻辑中"避免图表为空"的兜底方案此前取用官方硬件列表,
而在仅有叠加数据的选择下该列表恰好为空,于是得到空集合,把仍有数据的叠加柱全部
过滤掉。基于官方列表的重置逻辑也无法恢复:该列表在此变化过程中始终为空,因此
永远不会触发重新填充。现在兜底方案会取用所有仍有数据的硬件,涵盖官方与叠加两类。

重置逻辑的判定键也不再仅依赖官方硬件列表,而是改为用户的实际选择(模型、序列、
精度、运行日期)加上该列表。这样一来,仅有叠加数据的模型或序列切换会像其他选择
变更一样触发重置,而运行数据延迟到达(不改变上述任何一项)时仍不会清空用户筛选。
…om Substack / 移植 Vera Rubin NVL72 对比 GB200 NVL72 推理文章 (SemiAnalysisAI#629)

* feat(blog): port Vera Rubin NVL72 vs GB200 NVL72 inference TCO & architecture article from Substack

Republish the 2026-07-23 SemiAnalysis newsletter article on the
InferenceX blog with 26 locally hosted images, a Simplified Chinese
translation, and FAQ structured data. The subscriber-only tail
(MI355X comparison, Rubin software analysis) is behind the paywall
and is replaced by a pointer to the subscriber edition.

中文:将 2026-07-23 发布于 SemiAnalysis 通讯的《Vera Rubin NVL72 对比
GB200 NVL72?推理 TCO 与架构分析》一文移植到 InferenceX 博客,包含 26 张
本地托管图片、简体中文翻译及 FAQ 结构化数据。付费墙之后的内容(MI355X
对比、Rubin 软件分析)未包含,文末以订阅版链接代替。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(glossary): cite the Vera Rubin NVL72 article from relevant glossary entries

The glossary completeness test requires every blog post to be referenced
by at least one glossary entry. Add the new post to the entries it is
genuinely relevant to: total-cost-of-ownership, tokens-per-megawatt,
and nvlink.

中文:术语表完整性测试要求每篇博客文章至少被一个术语条目引用。将新文章
添加到与其真正相关的条目中:total-cost-of-ownership(总拥有成本)、
tokens-per-megawatt(每兆瓦 token 数)和 nvlink。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…sisAI#632)

Prefer vLLM when an official DeepSeek-V4-Pro Agentic Traces chart first resolves a cross-engine conflict, while preserving explicit sticky selections and unofficial preview behavior.\n\n中文:DeepSeek-V4-Pro Agentic Traces 官方图表首次处理跨引擎冲突时默认选择 vLLM,同时保留用户已选择的引擎及非官方预览行为。
…SemiAnalysisAI#633)

* feat(models): add Kimi-K3 as its own model bucket

Kimi K3 (moonshotai/Kimi-K3) is a new 2.8T total / 104B active
architecture built on Kimi Delta Attention (KDA) + gated MLA — not a K2
point release — so it gets its own DB bucket, dropdown option, and
compare slug instead of joining the K2.5/K2.6/K2.7-Code grouping. Source:
InferenceX run 30298924344 (kimik3, fp4, vLLM, MI355X, agentic traces).

- DB_MODEL_TO_DISPLAY: `kimik3` -> `Kimi-K3`; MODEL_TO_KEY:
  `moonshotai/Kimi-K3`. The `kimik3` prefix matches the DB key, so
  precision-suffixed forms (`kimik3-fp4`) fold in without an alias.
- Model enum + MODEL_CONFIG entry ("Kimi K3 2.8T", default category).
- Compare slug `kimi-k3` (dbKeys `['kimik3']`), added to KNOWN_MODELS.
  The bare `kimi` alias stays on the K2 series, matching how `minimax`
  stayed on M2 when M3 landed.
- Architecture diagram entry from the HF config.json + model card, plus a
  new `alternatingAttentionExpandable` flag: K3's hybrid is KDA + gated
  MLA, so its alternating blocks must not open DeepSeek V4's CSA/HCA
  local-vs-compressed drill-down (or its union-softmax caption). V4
  keeps that drill-down, which its existing `attentionExpandable: false`
  does not govern.

中文:新增 Kimi-K3 独立模型。Kimi K3(moonshotai/Kimi-K3)是基于 Kimi Delta
Attention(KDA)与 gated MLA 的全新架构(2.8T 总参数 / 104B 激活参数),并非 K2 的
小版本更新,因此单独建立 DB bucket、下拉选项和 compare slug,而不并入
K2.5/K2.6/K2.7-Code 分组;数据来源为 InferenceX run 30298924344(MI355X 上的
kimik3 fp4 vLLM agentic traces 基准测试)。`kimik3` 前缀与 DB key 一致,带精度后缀
的写法(`kimik3-fp4`)无需额外 alias 即可归并。compare 页新增 `kimi-k3` slug,裸
`kimi` alias 仍指向 K2 系列,与 M3 上线时 `minimax` 保持指向 M2 的处理一致。架构
图新增 `alternatingAttentionExpandable` 标志:K3 的混合注意力由 KDA 与 gated MLA
组成,其交替层模块不应展开 DeepSeek V4 的 CSA/HCA 下钻视图及对应说明文字,而 V4
仍保留该下钻(其已有的 `attentionExpandable: false` 并不控制这一路径)。

* fix(models): correct Kimi-K3 layer/expert accounting and fixture-gated tests

Addresses the three Cursor Bugbot findings on the K3 architecture entry and the
two e2e regressions the first commit introduced.

- Dense layer was double-counted: the diagram stacks the dense-FFN prefix above
  both alternating blocks, so 69 KDA + 24 MLA + 1 dense rendered 94 badges for a
  93-layer model. Layer 1 is a KDA layer *and* the dense layer, so it is carved
  out of the KDA count (68 + 24 + 1), the same partition DeepSeek V4 uses for its
  hash-routed prefix. A new suite-wide invariant test asserts stacked blocks
  never exceed numLayers for any model.
- Expert grid assumed a single shared expert: `drawExpertGrid` subtracted 1
  unconditionally, so K3 read "897 routed + 1 shared" against a model card that
  says 896 + 2. Added `sharedExperts` (defaults to 1) and moved the router label
  into an exported `expertRouterSummary` so it is unit-testable. Output is
  unchanged for every existing model.
- Alternation caption hardcoded "alternating every layer", which is only true of
  a 1:1 interleave. Added `alternatingNote`; K3 reads "gated MLA every 4th layer"
  and gpt-oss / V4 keep the default.

Test fixes:

- overview.cy.ts asserted 5 matrix rows. K3 is a default-category model, and the
  overview renders one row per DEFAULT_MODELS entry, so there are 6 — with K3
  collapsing to a coverage note (no fixture rows) exactly like GLM5.2.
- The K3 architecture e2e picked the model from the dropdown, which only lists
  models that have availability rows; the shared fixtures have none for kimik3.
  It now injects one availability row and visits `?g_model=Kimi-K3` directly.

中文:修正 Kimi-K3 的层数与专家数统计,并修复测试。(1)dense 层被重复计数:架构图
会在两个交替层模块之上再堆叠 dense 前缀模块,69 KDA + 24 MLA + 1 dense 会为 93 层
的模型渲染出 94 层徽章;第 1 层既是 KDA 层也是 dense 层,因此从 KDA 计数中扣除
(68 + 24 + 1),与 DeepSeek V4 处理 hash-routed 前缀的方式一致,并新增覆盖全部模型
的不变量测试。(2)专家网格默认只有 1 个共享专家:`drawExpertGrid` 固定减 1,导致 K3
显示为「897 routed + 1 shared」,与模型卡的 896 + 2 不符;新增 `sharedExperts` 字段
(默认为 1),并将路由标签抽取为可单元测试的 `expertRouterSummary`,其余模型输出保持
不变。(3)交替层说明文字固定为「alternating every layer」,仅适用于 1:1 交替;新增
`alternatingNote`,K3 显示「gated MLA every 4th layer」,gpt-oss 与 V4 维持默认。
测试修复:overview.cy.ts 原本断言 5 行矩阵,K3 属于 default 类别、overview 按
DEFAULT_MODELS 每个模型渲染一行,因此应为 6 行(K3 无 fixture 数据,与 GLM5.2 一样
折叠为覆盖率提示);K3 架构图 e2e 原本从下拉框选择模型,而下拉框只列出有 availability
数据的模型,共享 fixture 中没有 kimik3,现改为注入一条 availability 记录并直接访问
`?g_model=Kimi-K3`。

* test(agentic): update cross-engine resolution expectation to the vLLM default

Pre-existing failure on master, not introduced by this branch: PR SemiAnalysisAI#632 made
official DeepSeek-V4-Pro Agentic Traces charts prefer vLLM when they first
resolve a cross-engine conflict with no sticky selection, but did not update
`gpu-compare-agentic-detail.cy.ts`, which still asserted the previous
alphabetically-first winner (SGLang).

Verified against a local E2E_FIXTURES build: the toast renders and reads "Kept
vLLM and removed SGLang configs", with the selector on "B200 (vLLM)". The
original error read "element never found" only because the toast auto-dismisses
while the stale text assertion retries for 6s.

中文:修正跨引擎冲突解析的测试预期。该失败在 master 上已存在,并非本分支引入:PR SemiAnalysisAI#632
让官方 DeepSeek-V4-Pro Agentic Traces 图表在首次解析跨引擎冲突且无用户已选引擎时默认
选择 vLLM,但未同步更新 `gpu-compare-agentic-detail.cy.ts`,该用例仍断言此前按字母序
选出的 SGLang。已在本地 E2E_FIXTURES 构建中确认:提示条实际显示「Kept vLLM and removed
SGLang configs」,选择器显示「B200 (vLLM)」;原报错之所以是「找不到元素」,是因为过期的
文本断言重试 6 秒期间提示条已自动消失。

* fix(architecture): use the model's shared-expert count in the specs bar too

Follow-up to 48a014e, which routed the expert-grid subtitle through
`sharedExpertCount` but left two other call sites assuming a single shared
expert. The Experts figure in the specs bar rendered Kimi K3 as `16+1/898`
instead of `16+2/898`, contradicting the router line right below it.

Both remaining sites now read the count from the model: the specs bar and the
hash-routed prefix router (DeepSeek V4, count 1 — output unchanged). The K3 e2e
asserts the specs-bar figure alongside the router string.

中文:specs bar 同样改用模型自身的共享专家数。48a014e 已将专家网格副标题接入
`sharedExpertCount`,但仍有两处沿用「只有 1 个共享专家」的假设:specs bar 的 Experts
一栏把 Kimi K3 显示为 `16+1/898`(应为 `16+2/898`),与正下方的路由说明自相矛盾。现将
specs bar 与 hash-routed 前缀路由(DeepSeek V4,数量为 1,输出不变)两处都改为读取模型
自身的数量,并在 K3 的 e2e 中同时断言 specs bar 数值与路由字符串。

* fix(architecture): label K3's dense prefix and FFN activation from the model

Two more Bugbot findings on the Kimi K3 diagram, both real:

- The dense-FFN prefix block took its attention label from the model-wide
  `attentionType`, rendering "Hybrid Attention" for a block that is a KDA layer
  (config.json lists layer 1 under `kda_layers`), sitting next to correctly
  labelled KDA and gated-MLA blocks. Added `denseLayerAttentionLabel`, which
  falls back to the attention type for every uniform-attention model.
- The expert-grid and FFN drill-downs hardcoded SwiGLU/SiLU, contradicting K3's
  own "SiTU-GLU Activation" feature badge (`hidden_act: "situ"`). Added
  `ffnVariant` / `ffnGateActivation`, defaulting to SwiGLU/SiLU so every other
  model's captions are unchanged, asserted across the registry in a unit test.

The K3 e2e now covers the dense block's KDA label and the SiTU-GLU drill-down,
and no longer breaks on retry: it expands the alternating block only when still
collapsed, so a retry reports the assertion that actually failed instead of a
missing expand handle.

中文:K3 的 dense 前缀模块与 FFN 激活函数改为按模型标注。Bugbot 又发现两个真实问题:
(1)dense FFN 前缀模块沿用模型级 `attentionType`,为一个实为 KDA 层的模块渲染出
「Hybrid Attention」(config.json 将第 1 层列在 `kda_layers` 中),与旁边正确标注的
KDA、gated MLA 模块自相矛盾;新增 `denseLayerAttentionLabel`,对注意力机制统一的模型
仍回退到 attention type。(2)专家网格与 FFN 下钻视图固定写死 SwiGLU/SiLU,与 K3 自身的
「SiTU-GLU Activation」特性徽章冲突(`hidden_act: "situ"`);新增 `ffnVariant` /
`ffnGateActivation`,默认值为 SwiGLU/SiLU,其余模型文案保持不变,并在单元测试中对全部
模型做了断言。K3 的 e2e 现已覆盖 dense 模块的 KDA 标签与 SiTU-GLU 下钻,并修复了重试
问题:仅在交替层模块仍处于折叠状态时才展开,使重试报告真正失败的断言而非缺失的展开控件。
…ooltips (SemiAnalysisAI#634)

Artifacts from PP deployments (e.g. run 30314948116, Kimi-K3 TP8 PP2 on
B200 DGXC) emit prefill_pp/decode_pp, but the frontend ignored them: the
chart point label read "1xTP8+0xTP0" and tooltips showed no PP anywhere.

- parallelism-label: configSegmentLabel takes an optional pp and appends
  a "PP{n}" suffix only when pp > 1 (pp 0/1 renders nothing, keeping all
  existing labels byte-identical). Multinode-disagg labels drop a role
  whose pool doesn't exist (0 workers AND tp 0), so prefill-only agentic
  runs read "TP8PP2" instead of "1xTP8+0xTP0".
- data flow: pp has no configs-table column — the ingest mapper already
  auto-captures prefill_pp/decode_pp into the metrics JSONB for both DB
  rows and live-transformed ?unofficialrun= overlay rows, so
  rowToAggDataEntry surfaces pp/prefill_pp/decode_pp from metrics and
  the new keys (plus dcp/pcp sizes) are documented in METRIC_KEYS.
- total GPUs: createChartDataPoint folds pp into the aggregated-row GPU
  count (tp x pp); getPointLabel and the tooltip TP line switch to the
  raw decode_tp so a TP8 PP2 run doesn't mislabel as TP16.
- tooltips: per-role "PP: n" in the prefill/decode lines and a
  "Pipeline Parallelism" line for aggregated rows, hidden when pp <= 1;
  the parallelism block is now locale-aware (zh) like the cache block.

中文:前端图表标签与提示框现在支持流水线并行(PP)。pp > 1 时配置标签追加
"PP{n}" 后缀(如 TP8PP2);pp 为 0/1 时不显示。多节点 disagg 标签在某一
角色池不存在(worker 数为 0 且 TP 为 0)时仅渲染有效一侧,避免出现
"1xTP8+0xTP0"。pp 从 metrics JSONB 读取(官方 DB 行与 ?unofficialrun=
覆盖行走同一路径),聚合行的总 GPU 数按 tp × pp 折算,提示框新增 PP 行,
并为并行配置块补充中文本地化。

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…lysisAI#635)

* fix: hide branded watermarks on unofficial domains

中文:在非官方域名隐藏品牌水印,同时保留非官方运行警告水印。

* fix: prevent unofficial table watermark flash

中文:避免非官方域名的数据表格在 hydration 前短暂显示品牌水印。
… E2E Latency / 智能体场景 Interactivity 与 E2E Latency x 轴标题显示所选百分位 (SemiAnalysisAI#639)

* fix(inference): show selected percentile in agentic Interactivity / E2E Latency x-axis labels

On agentic scenarios the chart plots percentile fields (p75_intvty /
p90_intvty, p75_e2el / p90_e2el), but the x-axis labels for the regular
Interactivity and E2E Latency modes still rendered the raw config labels
("Interactivity (tok/s/user)", "End-to-end Latency (s)") because the
agentic relabel only REPLACED an existing leading statistic word and the
base config labels carry none. Extract the rewrite into
applyAgenticPercentileToXLabel, which prefixes the selected percentile
when absent and still replaces an existing prefix (TTFT override labels)
without doubling. Fixed-seq labels are untouched (isAgentic guard), and
the unofficial-run overlay path shares the same chartDefinition label so
it is covered by the same fix.

中文:智能体(agentic)场景下图表绘制的是百分位字段(p75_intvty /
p90_intvty、p75_e2el / p90_e2el),但常规 Interactivity 与 E2E Latency
模式的 x 轴标题仍显示原始配置标签,未带百分位前缀。本次将改写逻辑提取为
applyAgenticPercentileToXLabel:标签无统计词前缀时补上所选百分位,已有
前缀(如 TTFT 覆盖标签)时替换而不重复。固定序列场景标签保持不变;
非官方运行叠加路径复用同一 chartDefinition 标签,因此同样生效。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(e2e): make agentic axis-label assertions independent of the default x-axis mode

The agentic percentile axis-label assertions relied on Interactivity being
the agentic default x-axis mode. A parallel change makes OSL / E2EL the
agentic default, which would break these assertions on merge regardless of
landing order. Click the Interactivity / E2E mode buttons explicitly before
asserting labels, stub /api/v1/derived-agentic-metrics before the agentic
visits (so a derived default mode never sits on its loading skeleton), and
add the osl_per_e2el fields to the derived-metrics fixture. Fixed-seq
default assertions are unchanged.

中文:智能体百分位轴标签断言此前依赖 Interactivity 作为智能体默认
x 轴模式;另一并行改动将默认模式改为 OSL / E2EL,无论合并顺序都会
使这些断言失效。现改为在断言前显式点击 Interactivity / E2E 模式按钮,
在访问智能体页面前 stub /api/v1/derived-agentic-metrics(避免派生
默认模式停留在加载骨架屏),并在派生指标 fixture 中补充
osl_per_e2el 字段。固定序列默认断言保持不变。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…k preset (SemiAnalysisAI#640)

Retire the MiniMax M3 day-0 surfaces and point the landing banner and
modal at /inference?preset=kimi-k3-launch, following the "Featuring a
Day-0 Model" workflow in docs/adding-entities.md. New dismissal storage
keys (inferencex-kimi-k3-{banner,modal}-dismissed) so users who dismissed
the MiniMax M3 nudges still see the Kimi K3 ones; the minimax-m3-launch
preset stays routable but hidden so existing links keep resolving.

中文:按照 docs/adding-entities.md 的 Day-0 模型推广流程,将首页横幅、弹窗
和"首发概览"预设切换为 Kimi K3。更换新的 dismissal 存储键,使此前关闭过
MiniMax M3 横幅/弹窗的用户仍能看到 Kimi K3 通知;旧的 minimax-m3-launch
预设保留为隐藏状态,保证既有链接继续可用。

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Keep normal staging ingests cumulative and expose an explicit manual reset that restores the Neon branch from production. Re-staging remains idempotent for the selected workflow run.

中文:修复预发布流程,使常规写入累积保留已发布的基准测试运行;仅在显式手动重置时从生产环境恢复 Neon 分支。重复发布同一工作流运行仍保持幂等更新。
Restore the repository-wide bilingual contribution and website parity requirements.

中文:删除临时语言覆盖规则,恢复仓库范围内的双语贡献与网站同步要求。
…isAI#645)

* feat(overview): add scenario-aware comparisons

* fix(overview): address review feedback

* fix(overview): restore Chinese feature parity

Restore the Chinese landing CTAs, scenario-aware overview copy, and specific missing-result reasons after removing the temporary English-only override.

中文:恢复中文落地页入口、场景感知总览文案与具体缺失结果原因,确保删除临时仅英文覆盖规则后中英文功能保持一致。

* fix(overview): restore standard-decode fallback

Prefer speculative FP4/FP8 per platform, then fall back to labelled standard FP4/FP8 results. Select AgentX only when a model has no single-turn 8K/1K rows.\n\n中文:各平台优先选择推测解码 FP4/FP8;缺失时回退到明确标注的标准解码 FP4/FP8。仅当模型没有单轮 8K/1K 数据时选择 AgentX。
Preserve explicit non-disaggregated Dynamo deployments while retaining legacy inference for missing fields and decode-worker topology.

中文:尊重 Dynamo 产物中明确的非分离式部署标记,同时对缺失字段和存在解码工作进程池的旧产物保留兼容推断。
…Normalized E2E、会话时长与 Prefill TPS X 轴模式 (SemiAnalysisAI#644)

* feat(agentic): remove Normalized E2E / Session Time / Prefill TPS x-axis modes

Retire the three experimental agentic x-axis modes and everything that
existed solely to serve them, leaving Interactivity / E2E Latency / TTFT.

- chart: drop the three mode buttons, DERIVED_X_MODE_SPECS and the
  derived-metric fetch/remap plumbing in ChartDisplay; the remaining
  modes apply to both scenario kinds, so the agentic-only button filter
  (and its `mounted` SSR guard) goes too
- API/hook/db: delete /api/v1/derived-agentic-metrics, the
  useDerivedAgenticMetrics hook, and queries/derived-agentic-metrics.ts
- aggregate_stats v6: drop normalizedSessionTimeS, p90PrefillTpsPerUser
  and normalizedE2e400; mergeProfileStatsUpgrade no longer carries them
  forward, and the backfill's profile-only fast path now covers every
  v3+ bundle instead of only v3
- drop the NORMALIZED_E2E_OUTPUT_TOKENS constant and the overlay
  suppression helper that existed only for Normalized E2E

中文:移除三个实验性智能体 X 轴模式(Normalized E2E、会话时长、
Prefill TPS / user)及其专属实现,仅保留交互性 / 端到端延迟 / TTFT。
同时删除对应的 API 路由、React Query hook 与数据库查询模块;
aggregate_stats 升级至 v6,去掉三个已废弃字段,backfill 的
profile-only 快速路径扩展至所有 v3 及以上版本。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(e2e): make the Interactivity percentile assertion self-contained

The "switches back to Interactivity" test asserted a P75 axis label, but
nothing in it selected p75 — it inherited the selector state from the
Normalized E2E test that ran before it. Removing that test left the
selector on p90 and the assertion failed. Assert P90 there (the default)
and cover the p75 case in its own test that selects the percentile itself.

中文:「switches back to Interactivity」用例断言 P75 轴标签,但其自身
并未切换分位数,而是依赖此前 Normalized E2E 用例遗留的选择器状态。
该用例被移除后选择器停留在 p90,断言随之失败。现改为断言默认的 P90,
并将 p75 场景拆分为独立用例,由其自行切换分位数。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…miAnalysisAI#649)

Add GitHub workflow run 30405836523 to PURGED_RUNS so ingest skips it and
db:apply-overrides deletes its rows. The run is the ingest source run for
PR #2397 (kimik3-fp4-b300-vllm-agentic, 12 agentic points), an arm that
runs without speculative decoding; Kimi-K3 agentic coding is published
DSpark-only.

中文:将 GitHub workflow run 30405836523 加入 PURGED_RUNS,使 ingest 跳过
该 run,并由 db:apply-overrides 删除其数据库记录。该 run 是 PR #2397 的
ingest 源 run(kimik3-fp4-b300-vllm-agentic,12 个 agentic 数据点),
属于不启用投机解码的分支;Kimi-K3 智能体编码仅发布 DSpark 结果。

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sAI#650)

Treat non-disaggregated multinode serving as its own deployment mode and normalize its single aggregate TP/PP/EP topology across ingestion, charts, tooltips, and agentic detail navigation.

中文:将非分离式多节点推理作为独立部署模式,并在数据摄取、图表、提示信息和 Agentic 详情导航中统一使用单一聚合 TP/PP/EP 拓扑。
中文:fix(overview):明确标注推测解码方法
…AI#652)

Adds a supporter quote from Rodrigo Liang (Co-Founder & CEO, SambaNova)
to the /quotes supporters page and the homepage quote carousel, with the
SambaNova logo (official wordmark, 160px WebP) and a LinkedIn link.

The entry is placed at the end of the carousel block in QUOTES so the
"carousel orgs are listed first" ordering invariant still holds, and
'SambaNova' is appended to CAROUSEL_ORGS. Includes the required
Simplified Chinese translation (textZh) for the /zh pages.

中文:新增 SambaNova 联合创始人兼 CEO Rodrigo Liang 的支持者引言,同时展示在
/quotes 支持者页面和首页引言轮播中,并配有 SambaNova 官方标识(160px WebP)
与 LinkedIn 链接。

- 该条目放在 QUOTES 数组中轮播区块的末尾,以保持"轮播机构排在前面"的排序约定,
  并将 'SambaNova' 追加到 CAROUSEL_ORGS。
- 按仓库双语要求补充了 textZh 简体中文译文,供 /zh 页面使用。
… / 更新 RTX PRO 6000 hyperscaler 与 neocloud 每 GPU 小时单价 (SemiAnalysisAI#651)

* chore(pricing): update RTX PRO 6000 hyperscaler and neocloud $/GPU/hr

Refresh the RTX PRO 6000 Blackwell Server Edition rental rates in
HW_REGISTRY from the SemiAnalysis AI Cloud TCO model:

- hyperscaler (costh): $0.43 -> $0.677 /GPU/hr
- neocloud (costn): $0.676 -> $0.746 /GPU/hr

These feed every cost-per-million-token metric (y_costh / y_costn) in
the inference chart, throughput calculator, per-dollar compare pages,
and the tco-feed API. The 3-year rental tier (costr) is unchanged.

中文:更新 RTX PRO 6000 Blackwell Server Edition 在 HW_REGISTRY 中的租用
单价(数据来自 SemiAnalysis AI Cloud TCO 模型):hyperscaler(costh)由
$0.43 调整为 $0.677 /GPU/hr,neocloud(costn)由 $0.676 调整为 $0.746
/GPU/hr。这两个值会影响推理图表、吞吐量计算器、每美元性能对比页面以及
tco-feed API 中所有的每百万 token 成本指标。3 年租赁层级(costr)保持不变。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* test(overview): follow separated multi-node aggregate deployments

PR SemiAnalysisAI#650 made a non-disaggregated multi-node deployment its own serving
series, so the GB300 fixture's single-node (45 tok/s/user) and multi-node
aggregate (60 tok/s/user) points no longer blend into one curve and
DeepSeek-V4-Pro's GB300 cell has no read at @50. That PR updated
overview-data.test.ts but not overview.cy.ts, which still expected the
old interpolated ≈$1.19 estimate — six Overview specs have been failing
on master since it merged (they fail on any PR that touches
packages/app, including this one).

Point the estimate, evidence-date, cost-delta, mobile, and Chinese-sibling
assertions at cells that still carry a read (B200 ≈$0.89, GB200 +71%) and
assert the new GB300 outcome explicitly: a missing cell titled "no exact
@50 result" with no evidence date and no delta badge. Coverage of the
≈-estimate rendering, including the zh sr-only text, is preserved.

The GB200 badge saturates the alpha ramp at 0.40, which the browser
re-serializes as 0.4, so that assertion reads the computed background
color instead of the inline style attribute.

中文:PR SemiAnalysisAI#650 将非分离式多节点部署独立为单独的服务序列,因此 GB300 夹具中
的单节点点位(45 tok/s/用户)与多节点聚合点位(60 tok/s/用户)不再合并为
一条曲线,DeepSeek-V4-Pro 的 GB300 单元格在 @50 档位下没有结果。该 PR 更新
了 overview-data.test.ts,但未同步 overview.cy.ts,后者仍期望旧的插值估算值
≈$1.19——自其合并以来,master 上已有 6 个 Overview 用例持续失败(任何改动
packages/app 的 PR 都会触发,包括本 PR)。

现将估算值、证据日期、成本差异、移动端与中文页面的断言改为指向仍有结果的
单元格(B200 ≈$0.89、GB200 +71%),并显式断言 GB300 的新表现:标题为
「no exact @50 result」的缺失单元格,且没有证据日期与差异标签。≈ 估算值的
渲染覆盖(含中文 sr-only 文案)保持不变。GB200 的色阶徽章 alpha 值达到上限
0.40,浏览器会将其重新序列化为 0.4,因此该断言改为读取计算后的背景色而非
内联 style 属性。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
cquil11 and others added 27 commits August 9, 2026 15:16
Purge attempt 4 of run 29385297092 because it was produced with the outdated AgentX harness.
…lysisAI#711)

Apply one engine-comparability matrix to both Agentic Traces and 8K/1K,
scoped to a single hardware SKU. Per SKU:

  vLLM <-> SGLang          blocked (standard-token and MTP)
  TRTLLM <-> vLLM          allowed (MTP was blocked on Agentic)
  TRTLLM <-> SGLang        allowed (MTP was blocked on Agentic)
  TRTLLM <-> ATOM          allowed (MTP was blocked on Agentic)
  ATOM <-> vLLM or SGLang  allowed

Two changes produce it:

- Agentic Traces gains the same `exclusionFamilies` allowlist 8K/1K
  already had. It previously guarded every engine family while the
  agentic benchmark was new, which blocked TRTLLM and ATOM against vLLM
  and SGLang. Because the allowlist is matched before `groupAliases`,
  ATOM escapes the rule that folds it into SGLang's group.
- The model-level MTP spec becomes `scope: 'hardware'`, like the
  standard-token spec. It was global, so B200 SGLang MTP blocked
  MI355X vLLM MTP — a hardware comparison, which is the point of the
  chart. Same-SKU cross-engine MTP is still blocked.

The guard exists to stop two engines being read off one SKU's curve, not
to stop a chart holding two SKUs, so hardware scope is the rule
everywhere now. `EIGHTK_ONEK_EXCLUSION_FAMILIES` is renamed
`GUARDED_ENGINE_FAMILIES` since both scenarios share it.

中文:为「智能体轨迹」(Agentic Traces)与 8K/1K 两个场景应用同一套引擎
可比性矩阵,并限定在单一硬件 SKU 范围内。同一 SKU 下:vLLM ↔ SGLang
阻止(标准 token 与 MTP 均是);TRTLLM ↔ vLLM、TRTLLM ↔ SGLang、
TRTLLM ↔ ATOM 允许(此前在智能体场景下 MTP 被阻止);ATOM ↔ vLLM 或
SGLang 允许。

由两处改动实现:其一,智能体场景新增与 8K/1K 相同的 `exclusionFamilies`
允许列表——此前该场景在智能体基准测试尚新时对所有引擎family 加以限制,
导致 TRTLLM 与 ATOM 无法与 vLLM、SGLang 同时选中;由于允许列表在
`groupAliases` 之前匹配,ATOM 得以不受"折叠进 SGLang 分组"规则的影响。
其二,模型级 MTP 规则改为 `scope: 'hardware'`,与标准 token 规则一致——
此前为全局范围,导致选中 B200 SGLang MTP 后无法再选 MI355X vLLM MTP,
而这正是图表意在支持的硬件对比;同一 SKU 内的跨引擎 MTP 仍被阻止。

该限制的目的是避免在同一 SKU 的曲线上混读两种引擎,而非限制图表同时
展示两种硬件,因此现统一采用硬件范围。常量 `EIGHTK_ONEK_EXCLUSION_FAMILIES`
因两个场景共用而更名为 `GUARDED_ENGINE_FAMILIES`。

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…InferenceX" / 移植《在 NVIDIA GPU 上实现超高交互性?TileRT 登陆 InferenceX》 (SemiAnalysisAI#716)

* feat(blog): port "Ultra-High Interactivity on NVIDIA GPUs? TileRT on InferenceX"

Port the SemiAnalysis newsletter article of 2026-08-10 to the InferenceX
blog, following the same convention as the Vera Rubin port: slug matches
the newsletter slug, and the body opens with an "Originally published on
the SemiAnalysis newsletter" attribution line.

Covers the TileRT persistent Engine Kernel results on InferenceX (340
tok/s/user at 8k/1k and 494.2 tok/s/user at 1k/1k on an eight-GPU B200
node), what TileRT is and how it differs from CUDA graphs, the vLLM PD
disaggregation integration, the comparison against Cerebras / Groq /
SambaNova, why TileRT development is slow, and the AgentX next steps.

The final "Perf per TCO of TileRT Ultra Fast Speed" section is
subscriber-only on Substack and its body is not in the public page, so it
is not ported. The post ends with a pointer to the full article for that
analysis.

All 19 figures are pulled from the article and stored under
public/images/ultra-high-interactivity-on-nvidia/ with descriptive names.
Ships the required Simplified Chinese sibling at content/blog/zh/.

中文:将 2026 年 8 月 10 日的 SemiAnalysis 通讯文章移植到 InferenceX 博客,
沿用 Vera Rubin 移植的既有约定:slug 与通讯 slug 保持一致,正文开头附
"本文最初发布在 SemiAnalysis 通讯"的出处说明。

内容涵盖 TileRT 持久化 Engine Kernel 在 InferenceX 上的结果(8 卡 B200
节点在 8k/1k 下达 340 tok/s/user、1k/1k 下达 494.2 tok/s/user)、TileRT
是什么及其与 CUDA graphs 的区别、与 vLLM 的 PD 分离式集成、与 Cerebras/
Groq/SambaNova 的对比、TileRT 开发进展缓慢的原因,以及 AgentX 后续计划。

末节"Perf per TCO of TileRT Ultra Fast Speed"为 Substack 订阅者专享,其正文
不在公开页面中,故未移植;文末提供指向完整文章的链接。全部 19 张配图均取自
原文,以描述性文件名存放于 public/images/ultra-high-interactivity-on-nvidia/。
同时提供 AGENTS.md 要求的简体中文版本。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(glossary): reference the TileRT post from the glossary

glossary.test.ts asserts that the set of articles referenced across all
glossary entries equals the complete post library, so a new post that no
entry cites fails the suite. Add the TILERT slug constant and cite the
post from the six entries it actually belongs to: interactivity and
time-per-output-token (the article's headline metric and its inverse),
decode and disaggregated-inference (the persistent decode engine behind a
shared vLLM prefill pool), cuda (persistent Engine Kernel versus CUDA
graphs), and vllm (the MultiConnector integration).

中文:glossary.test.ts 会断言所有词条引用的文章集合等于完整的博客文章列表,
因此新增文章若未被任何词条引用便会导致测试失败。现新增 TILERT slug 常量,
并在六个确实相关的词条中引用该文章:interactivity 与 time-per-output-token
(文章的核心指标及其倒数)、decode 与 disaggregated-inference(共享 vLLM
预填充池背后的持久化解码引擎)、cuda(持久化 Engine Kernel 与 CUDA graphs
的对比),以及 vllm(MultiConnector 集成)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…sisAI#718)

* feat: add synchronized public api reference

中文:新增同步维护的公开 API 参考文档、OpenAPI 3.1 契约,以及用于防止接口与文档不一致的校验。

* docs: require api documentation synchronization checks

中文:要求所有 API 变更同步更新英文与中文参考文档、OpenAPI 契约和接口目录校验。
… gate (SemiAnalysisAI#717)

AgentX publishes on P90, so the percentile control is an insider
affordance rather than a normal chart filter. Hide it unless the ↑↑↓↓
konami feature gate is unlocked, on both surfaces that render it for the
agentic scenario: the inference chart controls and the TCO calculator.

No default changes were needed — the inference context, the calculator,
and the i_pctl URL-state default were already p90, so a locked user now
simply gets P90 with no control. Unlocking restores the selector and the
p75 option exactly as before.

ChartControls already had featureGateUnlocked in scope for the gated
Measured Energy metric group, so this reuses that pattern; the calculator
gains the useFeatureGate import.

中文:AgentX 以 P90 发布结果,因此"延迟百分位"选择器属于内部人员使用的
控件,而非常规图表筛选项。现将其隐藏,仅在通过 ↑↑↓↓ konami 功能开关解锁
后显示;改动覆盖智能体场景下渲染该控件的两个界面:推理图表控件区与 TCO
计算器。

无需改动默认值——推理上下文、计算器以及 i_pctl 的 URL 状态默认值本就是
p90,因此未解锁的用户现在直接得到 P90 且看不到该控件;解锁后选择器与 p75
选项的行为与此前完全一致。ChartControls 中因"Measured Energy"指标分组已
引入 featureGateUnlocked,此处复用同一模式;计算器新增 useFeatureGate 引入。

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…日期范围的误报 (SemiAnalysisAI#702)

Overview's per-cell "Compare curves" link pins both runs through i_dates and
sets no i_dstart/i_dend, so the picker read empty and rendered the red pulsing
error state even though the comparison was fully specified. The range is only
one of two additive sources of comparison series, and a pinned run can only be
expressed through i_dates — so gate the error state on resolveComparisonEntries,
the same predicate the chart itself uses.

中文:总览页每个单元格的“Compare curves”链接通过 i_dates 固定两次运行,不设置
i_dstart/i_dend,因此日期选择器显示为空并触发红色闪烁的错误状态,尽管对比其实已经
完整。日期范围只是对比曲线的两个叠加来源之一,而固定运行只能通过 i_dates 表达,
因此改用图表自身使用的 resolveComparisonEntries 作为判定条件。
…gation / 总览页基准硬件改为客户端推导并加固软导航 (SemiAnalysisAI#704)

* refactor(overview): split navigation context into data, reference and controls

A selector click moves the pending href immediately and the payload only
when the request settles. With both on one context value every uncached
selection pushed two complete scorecard renders. Split into data,
reference and controls contexts so each consumer re-renders only when the
thing it reads changes.

中文:将总览页导航 context 拆分为数据、参考硬件与控件三个 context。此前
选择器的待定状态与返回数据共用一个 context,导致每次未命中缓存的选择都会
触发两次完整的矩阵渲染。拆分后各消费者只在自身依赖变化时重新渲染。

* feat(overview): announce and dim the matrix while a selection loads

The URL changed the moment the selector was clicked but the matrix kept
showing the previous numbers with no signal that anything was happening.
Dim the card, mark it aria-busy and announce the load politely. Both
consumers sit outside OverviewPageBody so the affordance costs no matrix
render.

中文:选择器点击后 URL 立即更新,但矩阵仍显示旧数据且没有任何加载提示。
现在加载期间会将卡片变暗、标记 aria-busy 并向辅助技术播报。两个消费组件
都位于 OverviewPageBody 之外,因此该提示不会引发矩阵重新渲染。

* fix(overview): stop a settled commit from navigating after unmount

Leaving /overview through a soft navigation while a selector request is
in flight left the pending promise alive. On failure it rewrote the
address bar of whatever page the user had moved to and pushed them back
to /overview (or hard-reloaded, on the popstate path). Bump the
generation counter on unmount so both settled handlers bail.

中文:选择器请求进行中时通过软导航离开 /overview,未完成的 promise 仍然
存活。请求失败时它会改写用户当前所在页面的地址栏并把用户拉回 /overview
(popstate 路径下则是硬刷新)。现在卸载时递增导航代号,使成功与失败两个
回调都直接退出。

* fix(overview): replace instead of push on the JSON fallback

The failure path pushed an entry, rewound it to the previous URL, then
pushed again — two entries for one selection, a visible B→A→B flicker,
and a header language toggle left on the old search. Rewrite the entry
already on the stack instead.

中文:请求失败时先 push 一条历史记录,再回退到旧 URL,然后再次 push,
一次选择产生两条历史记录,地址栏出现 B→A→B 闪烁,且顶栏语言切换停留在
旧的查询串。现在直接原地改写已入栈的那条记录。

* fix(overview): skip the history write when the URL already matches

Re-clicking a selector whose request is still in flight made no second
request but pushed a second identical history entry, so Back appeared to
do nothing. Guard the history write only — guarding the whole commit
would swallow the retry after a failed load, which now leaves the URL on
the failed href.

中文:请求进行中时重复点击同一选择器不会发起第二次请求,却会再压入一条
完全相同的历史记录,导致后退看起来无效。这里只对历史写入加判断:若改为
整体跳过 commit,加载失败后(URL 已停留在失败的 href)重试点击会被吞掉。

* fix(overview): capture a PostHog pageview for soft selector navigations

Selector changes moved the URL without Next's router, so the app-wide
pageview tracker never saw them and every overview session collapsed to
its landing URL. Emit one $pageview per committed state.

中文:选择器改变 URL 时绕过了 Next 路由,全站 pageview 跟踪器无法感知,
导致每个总览页会话都只记录落地 URL。现在每次状态提交都会发送一次
$pageview。

* perf(overview): derive the comparison reference on the client

The `ref` selector chooses which column the percentages are measured
against and changes nothing else, yet every change cost a full JSON round
trip — and opening the select prefetched four more. Every cost it needs
is already in the payload, so derive it from the URL and recompute the
ratio per row. A reference change is now instant and request-free.

The server keeps resolving `ref` so copied URLs, SSR and no-JS still
render the right column.

中文:`ref` 选择器只决定百分比以哪一列为基准,其余数据完全不变,但此前
每次切换都要完整请求一次 JSON,打开下拉框还会额外预取四次。所需成本数据
payload 中本就齐全,因此改为从 URL 推导并按行重算比值,现在切换基准硬件
即时完成且不发请求。服务端仍继续解析 `ref`,以保证分享链接、SSR 与禁用
JS 场景下渲染正确的基准列。

* fix(overview): preserve unknown query params and normalize the data cache key

Two related URL bugs. The provider seeded its cache from the canonical
href rather than the address bar, so landing on /overview?tier=50 or with
a campaign tag missed the cache on the very first click and dropped any
fragment. And every distinct query string was its own cache key —
locally and at the CDN, where s-maxage is a day.

Adopt only the extras from the address bar, and key both the cache and
the request on one canonical identity built from the resolved params.

中文:修复两个相关的 URL 问题。provider 此前用规范化 href 而非地址栏播种
缓存,因此以 /overview?tier=50 或带营销参数的链接进入时,第一次点击必定
未命中缓存,且片段标识会被丢弃;同时每个不同的查询串都会成为独立缓存键,
本地与 CDN(s-maxage 为一天)皆是如此。现在只从地址栏采纳额外参数,并用
解析后参数构造的唯一规范标识作为缓存与请求的键。

* perf(overview): dwell before hover prefetch

Prefetch fired on every pointerenter and focus, so one sweep across the
six-option SLO strip issued six requests for states the user never chose.
Wait for a short dwell and cancel on leave; the click path still commits
synchronously.

中文:此前每次 pointerenter 与 focus 都会立即预取,指针扫过六个 SLO 选项
就会发出六次请求,而用户一个都没选。现在等待短暂停留后再预取,移开即
取消;点击路径仍然同步提交。

* perf(overview): drop tierValues from the wire config

tierValues is the interpolation input the server reads to produce a
tier's value — around a third of the raw payload, and no client code ever
touches it. Strip it at the assembly site (the trailing shorthand would
overwrite a strip done inside the helper) and give the client-facing type
its own name.

中文:tierValues 是服务端用于插值求出该 SLO 档位数值的输入,约占原始
payload 的三分之一,客户端从未读取。改为在装配处剥离(若在 helper 内部
剥离,后面的对象简写会重新覆盖回去),并为面向客户端的类型单独命名。

* fix(nav): guard the delayed in-app navigation retry

The unconditional second push 250 ms later re-rendered the destination
even when the first one had already landed. On overview that cancelled an
in-flight selector change and reverted its URL. Retry only while the
pathname has not moved.

中文:250 毫秒后的第二次 push 此前无条件执行,即使首次导航已经完成也会
重新渲染目标页面;在总览页这会取消进行中的选择器切换并回退其 URL。现在
仅在路径未发生变化时才重试。

* fix(header): scope the active-tab and language-toggle prefetch changes

Two header fixes. Clicking the tab you are already on refetched the route
and threw away the selector state in the URL; make it a no-op. And the
language toggle disabled prefetch on every route when only /overview
needs it — /overview is the one page that rewrites this href per
interaction.

中文:两处顶栏修复。点击当前所在的标签页会重新请求该路由并丢弃 URL 中的
选择器状态,现改为空操作;语言切换此前在所有路由上都关闭了预取,而实际
只有 /overview 需要——它是唯一会在每次交互中改写该 href 的页面。

* refactor(overview): move the route out of the dashboard shell

/overview showed no TabNav and read none of the dashboard's shared state,
yet DashboardShell still mounted GlobalFilterProvider and
UnofficialRunProvider around it — two API requests per cold load that
nothing consumed. Give it its own layout and drop the pathname special
case, so TabNav is unconditional again.

中文:/overview 不显示 TabNav,也不读取仪表板的任何共享状态,但
DashboardShell 仍为其挂载 GlobalFilterProvider 与 UnofficialRunProvider,
每次冷加载都会发出两个无人使用的 API 请求。现在该路由拥有自己的 layout,
并移除按路径特判的逻辑,TabNav 重新变为无条件渲染。

* fix(overview): keep the active comparison underline visible in light mode

border-transparent sat on the class both branches share, and Tailwind
emits it after border-secondary at equal specificity, so the active tab's
underline was transparent in light mode. Dark mode masked it because its
variant carries higher specificity. Move the inactive-only classes to the
inactive branch.

中文:border-transparent 此前位于两个分支共用的样式串中,而 Tailwind 在
同等优先级下将其输出在 border-secondary 之后,导致浅色模式下选中标签的
下划线完全透明;深色模式因变体选择器优先级更高而掩盖了该问题。现在把仅
适用于未选中状态的类移到未选中分支。

* style(overview): align the tier and engine chips with the segmented control

The hard bg-foreground/text-background inversion was unique to these two
controls; every other mutually-exclusive option group in the app uses the
segmented toggle's bg-muted/text-foreground. Match it, and drop the
inactive hover background that would otherwise be pixel-identical to the
selected state.

Not the brand accent: at text-xs it measures ~3.7:1 against the card,
below WCAG AA, where bg-muted keeps ~9:1.

中文:这两个控件此前使用 bg-foreground/text-background 的强反色,在全站
互斥选项组中独此一例,其余均采用 segmented toggle 的
bg-muted/text-foreground。现改为一致,并移除未选中项的 hover 背景色——
否则它与选中态在视觉上完全相同。未采用品牌强调色:在 text-xs 字号下其
对比度约为 3.7:1,低于 WCAG AA,而 bg-muted 可达约 9:1。

* fix(a11y): keep focus on the activated overview option

Each switcher renders the active option as a span and the rest as links,
so activating one changes the React element type at that position: the
focused node is destroyed and focus falls to <body>. Record the intent on
a keyboard-driven click and let the replacement claim it back.

中文:各选择器将选中项渲染为 span、其余渲染为链接,因此激活某一项会改变
该位置的 React 元素类型:被聚焦的节点被销毁,焦点落回 <body>。现在在
键盘触发的点击中记录意图,由替换后的元素重新取回焦点。

* fix(a11y): show missing-result reasons as visible text

Why a cell has no result was exposed only through a native title tooltip
and screen-reader text, so keyboard and touch users had no way to reach
it. Render it as a muted second line, mirroring the stack line on a
populated cell.

中文:单元格无结果的原因此前仅通过原生 title 提示与屏幕阅读器文本暴露,
键盘与触摸用户完全无法获取。现在改为渲染为次级弱化文本行,与有数据单元格
的技术栈行保持一致。

* perf(overview): render only the surface the viewport shows

The desktop matrix and the mobile list were both always mounted and one
was hidden with CSS, so every selection built the full cell tree twice.
Keep the Tailwind classes — they carry SSR and the pre-hydration frame —
and drop the off-screen surface only after hydration, so the rendered
output never differs from the server's.

中文:桌面矩阵与移动列表此前始终同时挂载,仅用 CSS 隐藏其一,因此每次
选择都会完整构建两遍单元格树。现保留 Tailwind 类以支撑 SSR 与水合前的
首帧,仅在水合完成后才移除不可见的那一套,确保渲染输出与服务端一致。

* perf(overview): cache the Intl formatters per locale

overviewFormatters ran unmemoized in the page body, rebuilding four ICU
formatters on every render. Cache lazily by locale — the inputs are two
fixed values. Hygiene rather than a headline win: the saving is fractions
of a millisecond per render.

中文:overviewFormatters 此前在页面组件体内未做缓存,每次渲染都会重建
四个 ICU 格式化器。现按 locale 惰性缓存(输入只有两个固定值)。这属于
代码卫生而非显著性能收益:每次渲染节省不足一毫秒。

* test(overview): cover the failure, popstate, pending and prefetch paths

The soft-navigation failure branch, the pending window, prefetch dedupe
and focus retention shipped untested. Add twelve vitest cases and five
Cypress cases; each was verified to fail against the unfixed behavior.

The router mock is now a hoisted stub with both push and replace — the
previous per-render spy made "not called" assertions unfalsifiable.

中文:软导航的失败分支、待定窗口、预取去重与焦点保持此前均无测试覆盖。
新增 12 个 vitest 用例与 5 个 Cypress 用例,每个都已验证在修复前的行为下
确实失败。router mock 改为提升到顶层、同时包含 push 与 replace 的稳定
stub——此前每次渲染新建 spy,使“未被调用”类断言永远无法失败。

* docs(architecture): record the overview BFF cache and URL rules

Three invariants a future change could silently break: one cache key per
data state, `ref` stays off that key, and useSearchParams() is
deliberately stale on /overview.

中文:记录三条未来改动可能无声破坏的约束:每个数据状态对应唯一缓存键、
`ref` 不参与该键、以及 /overview 上 useSearchParams() 有意保持过期。

* fix(header): suppress a nav click only on the exact current page

* fix(overview): keep a client-only reference change out of the pending state
…rection (SemiAnalysisAI#720)

The Measured Energy group was hidden behind the konami feature gate, but the
gate only ever hid the dropdown row: InferenceContext reads i_metric straight
from the URL with no allowlist, so ?i_metric=y_measuredJPerOutputToken already
renders these charts in production today, on official data. Make the group
selectable.

Three of the six axes (y_measuredAvgPower, y_measuredPrefillAvgPower,
y_measuredDecodeAvgPower) had no _roofline direction. Without one,
InferenceTable sorts a lower-is-better metric descending, and ScatterGraph
falls back to lower_right, which is backwards on the e2e block. Declare the
direction in both chart blocks, matching the J/token axes.

中文:实测能耗坐标轴组此前被 konami 特性开关隐藏,但该开关只隐藏了下拉选项本身——
InferenceContext 直接从 URL 读取 i_metric 且不做白名单校验,因此
?i_metric=y_measuredJPerOutputToken 今天就能在生产环境渲染这些图表,用的是正式数据。
本次改动让该分组可以正常选择。六个坐标轴中有三个缺少 _roofline 方向声明,导致表格视图
对“越低越好”的指标按降序排列,且 ScatterGraph 回退到 lower_right——在 e2e 图表块上方向
是反的。现为这三个坐标轴在两个图表块中补齐方向声明,与 J/token 系列保持一致。
…I#722)

Purge attempt 1 of run 30231719317 because it was produced with the outdated AgentX harness.
* chore(db): purge unsupported AgentX model attempts

Purge Kimi K2.5 run 29506569772 attempt 2 and MiniMax M2.7 run 29765418393 attempt 5 because AgentX is no longer supported for those models.

* chore(db): purge additional outdated AgentX attempts
… 卸载状态区分渐变与标签 (SemiAnalysisAI#729)

* feat(inference): split gradient labels by KV offload state

Gradient labels now append a +KV marker to the Pareto label when a point
ran with KV cache offloading enabled (kv_offloading tier, with legacy
offload_mode fallback via isKvOffloadEnabled). Offload-on and offload-off
points with the same parallelism therefore get distinct gradient color
territories, distinct pill labels, and distinct point colors. The +KV
marker parses as its own sub-strategy component, so same-parallelism
offload transitions blend with 0.5 similarity at the boundary.

中文:渐变标签现在会在启用 KV cache 卸载的数据点的 Pareto 标签后追加 +KV
标记(基于 kv_offloading 层级,并通过 isKvOffloadEnabled 兼容旧的
offload_mode 字段)。相同并行策略下,卸载开启与关闭的数据点将获得不同的
渐变颜色区段、不同的标签胶囊以及不同的点颜色。+KV 标记会被解析为独立的
子策略组件,因此同一并行策略的卸载切换边界会以 0.5 相似度平滑过渡。

* feat(inference): spell out KV offload gradient label as CPU KV Offloading

Per Slack feedback, the gradient label suffix is now ' + CPU KV Offloading'
instead of '+KV', so pills read e.g. 'TEP2 + CPU KV Offloading'.
parseLabelComponents trims split parts so the spaced suffix still parses
as its own component and same-parallelism offload transitions keep the
0.5-similarity blend.

中文:根据 Slack 反馈,渐变标签后缀由 '+KV' 改为 ' + CPU KV Offloading',
标签胶囊将显示如 'TEP2 + CPU KV Offloading'。parseLabelComponents 对拆分
后的组件做 trim 处理,使带空格的后缀仍被解析为独立组件,同一并行策略的
卸载切换边界保持 0.5 相似度的平滑过渡。
…isAI#695)

* fix(inference): merge agentic spec-decode points

Treat speculative decoding as point-level metadata for agentic scenarios while retaining fixed-sequence curve identity. Keep availability and run selection aligned, preserve overlapping point identity, and expose the method in bilingual tooltips.

中文:修复(推理):合并智能体场景中的投机解码点。智能体曲线不再按投机解码方式拆分,同时保持定长场景的现有曲线标识;同步可用性与运行筛选,避免重叠点丢失,并在中英文 tooltip 中展示每个点的投机解码方式。

* fix(inference): distinguish tracked agentic spec modes

Keep performance-over-time selections and historical matches distinct for agentic MTP and standard-decoding points while preserving fixed-sequence behavior.\n\n中文:区分智能体场景中被跟踪的投机解码模式,避免 Performance Over Time 将相同拓扑的 MTP 与标准解码点合并,同时保持定长场景行为不变。

* fix(inference): complete mixed agentic curves

Address independent review findings across run selection, history, overview, tracking, replay, labels, and changelog matching while preserving fixed-sequence behavior.

* fix(ai-chart): select one agentic workflow run

Apply the existing agentic latest-run selector to live AI chart benchmark data so mixed decode curves cannot combine workflows.

* fix: isolate mixed agentic decode identity

Preserve fixed-sequence chart, replay, changelog, cache-key, and API response semantics while merging speculative decode methods only for agentic scenarios.

* fix: hide standard decoding point labels

Render an agentic decode-method label only for active speculative methods such as MTP or EAGLE. Preserve fixed-sequence server row shape while retaining agentic run metadata.

* feat: mark agentic spec decoding with dashed plus

* style: match spec marker to offload halo

* style: simplify point marker legend labels

* refactor: move agentic optimization details to hover

* test: lock mixed agentic spec methods to one series

* test: align offload legend assertions
…alysisAI#730)

Remove Together AI (shown as "Tri Dao"), Nebius, White House, and UC San
Diego from CAROUSEL_ORGS. All four keep their quotes on /quotes and
/zh/quotes — the landing carousel renders QUOTES filtered by
CAROUSEL_ORGS, while the quotes page renders every entry, so trimming the
allowlist takes a supporter off the carousel without dropping them from
the site.

QUOTES itself is untouched; only the carousel allowlist changes. The
"Together AI" -> "Tri Dao" entry in CAROUSEL_LABELS is left in place (and
noted as inert) so the card reads correctly if the org is added back.

中文:将 Together AI(展示名为 "Tri Dao")、Nebius、White House 与 UC San
Diego 从 CAROUSEL_ORGS 中移除。四者在 /quotes 与 /zh/quotes 页面上的引用
均予保留——落地页轮播渲染的是按 CAROUSEL_ORGS 过滤后的 QUOTES,而引用页
渲染全部条目,因此仅调整该白名单即可让支持者从轮播中移除,而不会从站点
上消失。

QUOTES 本身未作改动,仅变更轮播白名单。CAROUSEL_LABELS 中
"Together AI" -> "Tri Dao" 的映射予以保留(并注明当前未生效),以便该组织
重新加入轮播时卡片仍显示正确名称。

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
… 智能体场景下将延迟类 X 轴指标收纳进高级菜单 (SemiAnalysisAI#731)

* feat(agentic): nest the latency x-axis modes under an Advanced menu

On the agentic-traces chart the x-axis strip carried four peers: E2E
Normalized Interactivity, Interactivity, E2E Latency, and TTFT. AgentX
headlines E2E Normalized Interactivity, so the three per-request latency
views now sit behind an "Advanced" menu beside it.

The trigger shows the active metric once one is picked ("Advanced: TTFT")
and carries the same active underline a tab would, so the strip still
says what the x-axis is plotting. It is a popover button rather than a
fifth TabsTrigger: Radix would otherwise treat it as a tab stop and steal
arrow-key navigation from the modes nested inside it.

Scoped to agentic on purpose. E2E Normalized Interactivity is
agentic-only, so collapsing the other three on fixed-sequence scenarios
would leave the strip with nothing in it; 8K/1K and friends keep today's
flat three-tab row.

中文:在智能体轨迹(agentic-traces)图表中,X 轴切换条原本并列四项:端到端
归一化交互性、交互性、端到端延迟、TTFT。由于 AgentX 以端到端归一化交互性为
主指标,现将其余三个逐请求延迟视图收纳进其旁边的"高级"菜单。

选中某项后,触发器会显示当前指标(如"高级:TTFT"),并保留与标签页一致的
选中下划线,因此切换条仍能表明 X 轴当前绘制的指标。该触发器是弹出菜单按钮
而非第五个 TabsTrigger:否则 Radix 会将其视为一个标签停靠点,从而抢走其内部
各模式的方向键导航。

此改动有意仅限智能体场景:端到端归一化交互性为智能体专有,若在固定序列场景
下同样收纳其余三项,切换条将空无一物;8K/1K 等场景保持现有的三标签平铺布局。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* fix(agentic): address Bugbot findings on the Advanced x-axis menu

Two review findings on the Advanced menu:

- Medium: Radix Tabs activates on focus by default, so focusing a
  trigger fires onValueChange. On agentic the strip renders one tab while
  the selected mode may live in the Advanced menu, so tabbing to that
  trigger could snap the x-axis back to E2E Normalized Interactivity. Set
  activationMode="manual" on the Tabs root — arrow keys move focus,
  Enter/Space commits. That also suits a control whose every change
  redraws the chart.
- Low: the trigger set a static aria-label of "Advanced", which replaced
  the accessible name, so screen readers heard "Advanced" even when the
  visible text read "Advanced: TTFT". Dropped it; the accessible name now
  comes from the visible text.

中文:处理评审提出的两个问题。其一(中等):Radix Tabs 默认在获得焦点时即
激活,因此聚焦触发器会触发 onValueChange;在智能体场景下切换条仅渲染一个
标签,而当前选中的模式可能位于"高级"菜单中,此时用 Tab 键聚焦该标签会导致
X 轴被重置回端到端归一化交互性。现在 Tabs 根节点设置 activationMode="manual"
——方向键仅移动焦点,需 Enter/Space 才提交;对于每次变更都会重绘图表的控件,
这一行为也更合适。其二(低):触发器原先固定设置 aria-label 为 "Advanced",
覆盖了可访问名称,导致屏幕阅读器在可见文本为 "Advanced: TTFT" 时仍只读出
"Advanced";现已移除该属性,可访问名称改由可见文本提供。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…(1周/1月/2月/3月) (SemiAnalysisAI#732)

* feat(overview): selectable history comparison window (1w/1m/2m/3m)

* test(overview): ignore aria-hidden radix bridge in scroller guard

* fix(overview): pending-URL history window select, register overview-data digest
…60814

# Conflicts:
#	packages/app/src/lib/compare-slug.test.ts
#	packages/app/src/lib/compare-slug.ts
#	packages/constants/src/gpu-keys.ts
@aistackdev
aistackdev merged commit af1752a into master Aug 14, 2026
4 of 15 checks passed
aistackdev pushed a commit that referenced this pull request Aug 14, 2026
… 修复部署:预构建数据库迁移步骤改用 bun 而非 pnpm

Upstream sync (PR #19) switched the project's packageManager to
bun@1.3.14 and dropped pnpm-lock.yaml/pnpm-workspace.yaml, so the
migration container's `corepack prepare pnpm@latest` now fails with
"Unsupported package manager specification". Swap the throwaway
migration container from node:24-bookworm-slim + pnpm to
oven/bun:1.3.14-slim + bun, mirroring what tests-unit.yml/ingest-results.yml
already do.

上游同步(PR #19)将项目的 packageManager 切换为 bun@1.3.14,并移除了
pnpm-lock.yaml/pnpm-workspace.yaml,导致迁移容器中的
`corepack prepare pnpm@latest` 报错 "Unsupported package manager
specification"。将一次性迁移容器从 node:24-bookworm-slim + pnpm 换成
oven/bun:1.3.14-slim + bun,与 tests-unit.yml/ingest-results.yml 的做法保持一致。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
aistackdev pushed a commit that referenced this pull request Aug 14, 2026
…生产 Dockerfile 从 pnpm 迁移到 bun

Upstream sync (PR #19) dropped pnpm-lock.yaml/pnpm-workspace.yaml in
favor of bun.lock, so the Dockerfile's `pnpm install --frozen-lockfile`
had nothing to install from (COPY pnpm-workspace.yaml failed outright).
Switch both build stages to oven/bun:1.3.14-slim, copy bun.lock plus
all 4 workspace package.json files (packages/mcp was missing from the
COPY list, causing a lockfile-mismatch error), and swap pnpm/corepack
commands for bun equivalents. Verified locally end-to-end: bun install
+ migrate + full `docker build` (against a real local Postgres, secrets
mounted like the real workflow) + container boots and serves 200.

上游同步(PR #19)移除了 pnpm-lock.yaml/pnpm-workspace.yaml,改用
bun.lock,导致 Dockerfile 里的 `pnpm install --frozen-lockfile` 无源可装
(COPY pnpm-workspace.yaml 直接报错)。将两个构建阶段都换成
oven/bun:1.3.14-slim,改为拷贝 bun.lock 及全部 4 个 workspace 的
package.json(此前 COPY 列表漏掉了 packages/mcp,导致 lockfile 不匹配
报错),并把 pnpm/corepack 命令替换为对应的 bun 命令。已在本地完整验证:
bun install + migrate + 完整 `docker build`(挂载真实本地 Postgres 和
secret,模拟真实工作流)+ 容器启动并返回 200。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants