Skip to content

[PR] test(e2e): fork-adoption relay echoes plain text, not rendered ref tags — unblocks v0.1.210 release - #5377

Merged
ranxianglei merged 1 commit into
masterfrom
2026-11-01_fork-adoption-relay-tag-strip
Oct 31, 2026
Merged

ranxianglei merged 1 commit into
masterfrom
2026-11-01_fork-adoption-relay-tag-strip

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

修 e2e-dsh-plugin-lane / fork-adoption 双红(v0.1.210 发版卡点)

这是啥问题

v0.1.210(#5368)把消息时间戳/ref 标签改成默认开启后,CI 的 e2e-dsh-plugin-lane 里 tests/fork-adoption.test.ts 两个用例全红:AssertionError: 'parent must have a folded block (got 0)'。Release 工作流因此走不完。

根本原因(不是时间戳功能本身的 bug,是测试 fixture 没跟上默认值)

链条(本地逐步钉死,含临时插桩证据):

  1. 这个 e2e 的 mock relay 会把最后一条 user 消息的前 48 个字符原样回显进每条模型回复(relayReply,用于模拟"模型在应答里提到上一轮内容")。
  2. 标签默认开后,上游请求体里 user 消息的真实形状是「一行 <acp tokens="…" type="text" time="…">mNNNNN</acp> + 换行 + 正文」。前 48 字符恰好是半个未闭合的 render tag。
  3. bili 对模型输出有防泄漏 sanitizer(src/loop/tag-echo-filter.ts,src/stream.ts:1575 消费)——模型回复里出现自家 tag 就剥掉。它正确地剥掉了回显进来的半个 tag 及其后全部内容,存下来的 assistant 消息只剩 16 字符(run reply 6 to <)。
  4. kernel 软保护区按配置 preserveRecentTokens=400 从尾部往前数:assistant 回复都缩成 ~4 token 后,400 token 窗口真的覆盖了整个视图(插桩实测:default-on 保护集 = 全部 13/15/… 条;pin 0 时只护尾部 3 条)。压缩 m1..m3 收到合法 no-op 收据("entirely inside the protected zone"),用例断言"父会话必须有折叠块"失败。

结论:sanitize 行为正确、保护区计算正确、时间戳渲染正确——错的是 fixture 假设了"上游请求体里没有标签"这个 v0.1.209 时代才成立的隐含前提。

修法

relayReply 改成只回显真实文本:剥掉开头的 marker 行,取换行之后的正文(无标签环境走同一条路径,行为不变)。9 行改动,仅测试文件,零产品代码变化,不削弱任何生产防线。

验证(本地,正式 CI 留给远端)

  • default-on(=CI 真实形状,改前红):2/2 ✔
  • BILI_MESSAGE_TIMESTAMPS=0(pin,改前绿):2/2 ✔
  • tsc --noEmit exit 0
  • 顺带核过同 workflow 其他 e2e 文件没有同款"回显客户端字节"反模式

合并建议

单文件测试修复,无行为面,可直合。合入后重跑 e2e-dsh-plugin-lane + Release 工作流即可解卡。(另一条红 docs-sync 是 #5264 文档表未再生成,与本 PR 无关,另开。)

…d ref tags (#5368)

v0.1.210 turned ref-marker rendering on by default (#5368). This fixture's
mock relay echoed the first 48 chars of the last user message into every
model reply; with tags on by default that slice is a partial '<acp ...'
render-tag fragment. The host sanitizer (src/loop/tag-echo-filter.ts) then
correctly stripped the leaked tag-and-onward, leaving 16-char assistant
messages. The kernel's soft-protected zone (preserveRecentTokens=400) then
genuinely covered the whole 5-message view, so the scenario's compress call
no-op'd and 'parent must have a folded block' failed.

Echo the real text instead: strip the leading marker line and keep the text
below it, so the relay behaves like a real model that never re-emits render
tags. Verified both env shapes: default-on (CI shape, red before) and
BILI_MESSAGE_TIMESTAMPS=0 (pin) — 2/2 green either way.

@ranxianglei ranxianglei left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查完成。结论:通过,可直合;无阻塞项。

核验记录:

  1. 根因链独立复现:临时插桩 computeProtectedRefs 双向对比——default-on 时 mock relay 回显进回复的是半个未闭合 <acp tokens=… fragment(user 消息 wire 形状 = marker 行 + \n + 正文,前 48 字符必落在 tag 内),src/loop/tag-echo-filter.ts(src/stream.ts:1575)正确剥掉后 assistant 消息只剩 16 字符;保护集实测从「尾部 3 条」变成「全部 N 条」,compress 合法 no-op,断言失败。sanitizer/保护区/渲染三方行为均正确,锅在 fixture。
  2. 修复最小且对症:单文件 +9/-1,只改 relayReply 的回显取材;剥离正则锚定完整 marker 行 + 换行取正文,无标签环境(pin 0 / 老客户端)走同一路径零变化;未动任何产品代码、未削弱 tag-echo 防线。
  3. 验证:default-on(CI 形状)2/2 ✔、BILI_MESSAGE_TIMESTAMPS=0 2/2 ✔、tsc exit 0;已扫同 workflow 其他 e2e 无同款"原样回显客户端字节"反模式。
  4. 备注:合入后记得手动重跑 Release 工作流(#5373);主 CI 的另一条红是 docs-sync(#5264 的 yaml seed 描述改动没跑 tools/gen-config-docs.mjs generate,CONFIGURATION.md/.zh-CN.md 各差一行),与本 PR 无关,另开小 PR 处理。

@github-actions

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: 2026-11-01_fork-adoption-relay-tag-strip (c20891a)

Latest build — install this exact version

npm install -g billion-context@0.0.7594-pr.5377.e1aec5f

This exact version is immutable and reproducible. The rolling pr tag tracks the newest test build across all PRs.

Recent builds (commit → version)

commit version build
c20891a billion-context@0.0.7594-pr.5377.e1aec5f build

Download artifact

  1. Download the artifact from the Actions run
  2. Extract the tarball and install:
tar xzf billion-context-pr5377.tgz
npm install -g package

Install instructions are refreshed on each push.

@ranxianglei
ranxianglei merged commit e209109 into master Oct 31, 2026
48 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

📦 Merged Build Published

This merge to master was published as 0.0.979-master.e209109 (rolling master tag).

npm install -g billion-context@0.0.979-master.e209109  # this exact build
npm install -g billion-context@master  # always the newest merged build

npm view billion-context@master prints the current version at any time.

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.

1 participant