Skip to content

[PR] Web Panel: Handoff Documentation and Collapsed Tree Diagram Rendering Upgrade (eWork-Level Rendering, Appendix Sectionin | Web 面板:交接文档与压缩树图渲染升级(eWork 级渲染、附录分节、冻结快照水合) - #6260

Merged
ranxianglei merged 5 commits into
masterfrom
handoff-render-ework
Nov 11, 2026

Conversation

@ranxianglei

Copy link
Copy Markdown
Owner

改了什么

交接文档与压缩树图三个渲染问题,一次修完(参考 eWork 的会话视图做法,零新增运行时依赖):

1. 交接文档渲染升级到 eWork 级别(此前:整篇纯文本,无 Markdown、无高亮)

  • 正文按 Markdown 渲染(行内码/粗体/链接/列表/表格/围栏代码),新增手写的语法高亮(JSON / diff / C 系 / Python / Shell,明暗双主题),工具调用与输出卡带语言标签 + 复制按钮
  • 消息按角色卡片呈现(User/Assistant/Tool 徽章 + 角色色左边框),思考过程默认收起
  • 客户端与浏览器端共用同一个自包含渲染核心 src/web/mdrender.ts(.toString() 内联进 Web IIFE,生产构建零依赖守卫 check-dist-external 通过)

2. 「Compressed block summaries」附录不再被吞进最后一条消息

  • 长会话的交接文档里,export 端追加在对话后的整节块摘要(80+ 个 ### Block bN、数百行)此前全部落进最后一个 assistant 卡片,看起来像「压缩消息被追加成一条巨型消息」。现在 ## 级标题识别为独立分节,### Block bN — topic 逐条渲染为小块卡片(块号 + 主题 + tier/token 元行 + Markdown 正文)

3. 压缩树图:悬停标题一闪即逝 + 点击块后看不到消息内容

  • 悬停提示改为页面内常驻浮层(完整块号/tier/消息范围/主题/tokens/消息数),轮询重画不再打断;悬停时节点上的主题行原地扩宽到 ~20 字
  • 5 秒轮询只回传瘦节点,此前每次 tick 重画后所有标题退化成光秃秃的块号——现在重画前与详情富块按 blockId 合并
  • 点击压缩块的消息行此前几乎全是「消息已不在会话中」(宿主原生压缩剪掉了上下文里的字节)。现在从块落盘时保存的冻结快照按标记锚定水合原文:每个 mNNNNN 标记用恒等锚(标记号=该位当前 ref)或冻结 span 算术锚(标记冻结编号 − span 起点 = 位序,冷加载 restamp 免疫)锚死,锚间段条数平衡才按位 zip;无法证明的位置保持诚实 missing,宁缺不错位

验证

  • web 面板测试全绿 112/112(含新增水合 7 用例,覆盖 restamp 恢复 / ref 巧合碰撞 / 外来标记整块拒 + click-to-open 双向断言);npm run typecheck、npm run build(含零运行时依赖守卫)通过
  • 真实大会话(253 块 / 9771 个直接消息引用)实测:7789 条(80%)恢复真实预览与原文(此前 52%);b27 全块 127/127 恢复,块摘要自引的两条消息(「看看状态 我发现很多都不正常」/「状态我查完了…」)逐字对上

…ght + role cards)

The sessions' handoff (交接文档) tab rendered every message body as
escaped plain text: markdown in assistant replies stayed literal, code
fences showed raw backticks, and tool input/output was one giant
unhighlighted pre with no copy button.

- new src/web/mdrender.ts: single escape-first Markdown + hand-rolled
  syntax-highlight core (json/diff/js/ts/py/sh lexers, GitHub light+dark
  palettes, unknown languages degrade to escaped text, zero runtime
  deps). Inlined into the browser IIFE via .toString() exactly like the
  JSONC helpers; tests/mdrender.test.ts pins behavior plus the
  self-contained inlining contract (esbuild-minified .toString() must
  run in a bare scope, mirroring the tsup pipeline).
- web/markdown.ts becomes a thin wrapper over the same core, so the
  server-rendered handoff fallback and blog articles gain highlighting
  too.
- client.ts renderHandoffMd: role cards (user/assistant/tool left border
  + badge), markdown-rendered bodies incl. thinking chains (collapsed by
  default), structured tool cards (input/output label, language detection
  json/diff, per-block copy button, JSON pretty-print, open when <= 20
  lines), document meta (title/session id/token stats) rendered as a
  key/value box instead of being skipped.
- styles.ts: card/token CSS vars in light + both dark palettes (#2559
  verbatim-equality kept); i18n: det.io_in/det.io_out.
- tests/web-handoff-roles.test.ts adapted to the new markup; the #2065
  invariant (in-body headings never become role dividers) is preserved.

CHANGELOG + docs/architecture/webui(.zh-CN).md + reference/architecture.md
file map updated (architecture-docs lane green).
…ts own section

The client renderer only recognized ### user/assistant/tool as block
dividers (#2065), so the export.ts #845 appendix ('## Compressed block
summaries' + one '### Block bN' entry per active block) landed inside
the last assistant card — on a session with 72 active blocks that was
~700 lines swallowed into one card. '## ' headings after the
Conversation heading now close the role cards and open a section;
'### Block bN — topic' entries render as small cards (mono block id +
topic + tier/token meta line + Markdown body). #2065 invariant intact:
in-body '### 7.1 …' lines are still content.
…for pruned leaf messages

Two fixes for the session-detail 压缩结构 tab (#3917 tree):

1. Node titles flickered away on select/poll redraw because they were
   native SVG <title> elements. Replaced with a persistent in-page
   floating tip (.g-tip): follows the pointer, shows block id/tier/
   message span/full topic/tokens/message count, and survives node
   selection and the 5s live-tree redraws (re-anchored after redraw).
   The <g> keeps an aria-label for accessibility.

2. Clicking a leaf block listed its message refs (mNNNNN) but every
   row said 'no longer in the session' — host native compaction prunes
   the messages from context, so the bytes were nowhere to look. They
   ARE on disk though: collectBlockContent froze each original message
   ([role] / [role • tool] header + text, pi-host user messages carry
   their ACP ref marker) into the block's full snapshot. New
   frozen-snapshot hydration: for a LEAF block whose full snapshot
   parsed fragment count equals its direct-message ref count — with
   every ACP marker cross-checking its own ledger position — the rows
   re-align by position (preview + click-to-open via /message?ref=).
   Count mismatch, marker conflict, or non-leaf spans (children mixed
   into the snapshot, position meaningless) abort the whole block and
   keep the honest 'missing' marker — never serve shifted bytes.

Measured on a 253-block/9771-ref session: 5072 (52%) leaf messages
recovered their real previews and text; the rest stay honest misses.

Regressions: tests/web-blocks-tree.test.ts (2 new cases: positional
hydration + the three refusal arms), web-sessions/web-handoff-roles/
mdrender and the web sandbox suites stay green; typecheck +
check-dist-external (zero runtime deps) pass.
…snapshot hydration

- compression tree: hovering a node now widens its topic line in place
  (~20 chars) and the .g-tip overlay follows the pointer; a 5s live-tree
  tick previously redrew the graph with lean nodes and degraded every
  topic back to a bare block id — ticks now merge onto the rich detail
  blocks by blockId before redrawing (structure/active/spans win)
- snapshot hydration gains a restamp-proof ARITHMETIC anchor: the
  marker's frozen number minus the block's frozen span start equals the
  snapshot position. Cold-load restamping (#5196 parked bands take fresh
  numbers) renumbers whole blocks, which invalidated the identity proof
  (marker number no longer in the ref list) and left entire renumbered
  blocks (b27: 127/127 missing) at honest-misses although their frozen
  snapshot held every byte. Identity still wins where the marker number
  is current; a marker proving neither aborts the block; unbalanced
  segments stay missing. Measured on the 253-block/9771-ref session:
  7789 refs (80%) now hydrate (was 5072/52%), b27 fully recovered
- tests/web-blocks-tree.test.ts: +3 hydration cases (restamped block
  recovered / arithmetic beats a coincidental ref collision /
  unanchorable marker rejects the whole block incl. click-to-open);
  marker-shift fixture span pinned so the case stays legacy-anchored
@github-actions

github-actions Bot commented Nov 11, 2026 •

Copy link
Copy Markdown
Contributor

📦 Built Package Artifact

Branch: handoff-render-ework (8c69ec2)

Latest build — install this exact version

npm install -g billion-context@0.0.9155-pr.6260.b403886

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
8c69ec2 billion-context@0.0.9155-pr.6260.b403886 build
4b6522a billion-context@0.0.9151-pr.6260.77e5181 build

Download artifact

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

Install instructions are refreshed on each push.

@ranxianglei ranxianglei changed the title Web 面板:交接文档与压缩树图渲染升级(eWork 级渲染、附录分节、冻结快照水合) [PR] Web Panel: Handoff Documentation and Collapsed Tree Diagram Rendering Upgrade (eWork-Level Rendering, Appendix Sectionin | Web 面板:交接文档与压缩树图渲染升级(eWork 级渲染、附录分节、冻结快照水合) Nov 11, 2026
@ranxianglei
ranxianglei merged commit c26c31a into master Nov 11, 2026
48 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

📦 Merged Build Published

This merge to master was published as 0.0.1176-master.c26c31a (rolling master tag).

npm install -g billion-context@0.0.1176-master.c26c31a  # 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.

@ranxianglei ranxianglei added enhancement New feature or request p2 scope/ui labels Nov 11, 2026
ranxianglei pushed a commit that referenced this pull request Nov 12, 2026
master moved past the previous sync (dc041dd) by the web handoff-render
(#6260) + anthropic trailing-system (#5432/#5441) + snapshot-write-lifecycle
(#6186) landings. None of those commits modify src/plugin.ts or
src/agent/fork-adopt.ts (master's version of both == merge-base), so this
merge is clean and preserves the #5123/#4266 union resolution untouched.
ranxianglei pushed a commit that referenced this pull request Nov 12, 2026
Master advanced past the dc041dd merged earlier (web handoff rendering,
anthropic trailing-system tails #5432/#5441, snapshot write lifecycle #6186,
handoff-render #6260). Clean auto-merge — none of those commits touch the
side-lane surface (handle.ts / side-request.ts / side-lane tests), so no
conflicts and no logic change.
ranxianglei pushed a commit to john08281/billion-context that referenced this pull request Nov 12, 2026
… round 9)

Master advanced 33104b1 -> c26c31a (ranxianglei#6260, ranxianglei#5441, ranxianglei#6186, ranxianglei#5774,
ranxianglei#6166 et al.). Clean auto-merge, no conflicts: the new window's
blockOps work (ranxianglei#5765/ranxianglei#6166) and this PR's decide-lane keys land in
different regions of every shared file.

Also completes the round-8 docs regeneration that was left unstaged:
the committed head carried the decide-lane keys in the compress.yaml
seed but not in the generated output. Re-ran
node tools/gen-config-docs.mjs generate on the merged seed (341
entries; i18n ok: 256 keys, EN/ZH equal) — generated output now
matches the seed in docs/configuration[.zh-CN].md, website/main.js
and website/docs/index.html (blockOps + decide-lane keys, both
languages).

Verified: tsc --noEmit clean; unused-exports gate clean; targeted
suites green (nudge-decide + issue3004 selfheal + config-surface-guard
+ nudge-model-decided e2e). Full-suite verdict = remote CI.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request p2 scope/ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant