Skip to content

Rendering Pipeline zh

Hermes Agent edited this page Oct 1, 2026 · 2 revisions

渲染管线

English | 中文 | 日本語 | 한국어 | Español | Português | Русский

助手气泡的 Markdown → 可信 HTML 全链路在 lib/sidepanel/render.js。顺序不可换:

  1. fixCjkEmphasisSpacing(CJK 邻接 ** 补丁——字符类刻意镜像 marked 的断句规则:标点 = \p{P}∪\p{S},邻接 = 任意字母数字)
  2. 抽取 <think> 块 → 占位符
  3. 抽取块级公式 $$…$$ / \[…\]
  4. 抽取行内公式 $…$ / \(…\)——两道守卫:
    • \\ 和 \$ 这两个 Markdown 转义先被原样消费(\$8K 是字面美元,2026-09-30 MRR 表格报告);
    • 行内 $ 采纳 Pandoc 定界规则:开合必须贴紧内容、闭合 $ 后跟数字则否决(从**$8K**、**$20K** 的裸 $ 曾配对进 KaTeX,* 渲染成 ∗——2026-10-01 报告)。被否决的配对原样留给 marked。
  5. marked.parse → 6. DOMPurify 消毒 → 7. KaTeX worker 批量渲染公式并回填(消毒之后,MathML 属性不经过 DOMPurify)→ 8. 回填 think 折叠块。

流式渲染:块级提交(ADR-0011)

  • renderStreamingSafe(同步)只负责每帧的尾部;已完成的 Markdown 块只提交一次(findStreamingBlockBoundary 找安全切点:空行边界、不在围栏内、下一行不是列表项),每帧只重解析开口尾巴——把 O(n²) 压成 O(n)。开围栏走快速路径(直接 <pre><code> + textContent,零 marked 调用)。
  • 显影节奏由 vendored markstream-core 的 reveal pacer 负责(makeStreamRenderer 返回闭包,重赋值前必须 .destroy())。DONE 后整体重渲一遍 renderSafe(KaTeX + 完整 think),修正流式近似。
  • 历史渲染懒升级:IntersectionObserver 接近视口才升 KaTeX/mermaid;content-visibility:auto 在 .cv-settled(双 rAF 后)才生效——首屏与定位期间绝不启用。
  • KaTeX 卸载:katex-threshold.js 决定是否进 worker(katex.worker.js,批量、带缓存、失败自动回落同步)。

六个围栏渲染器(```lang → 实时渲染替换,无按钮)

围栏 渲染器 vendor 要点
```mermaid renderMermaid mermaid securityLevel:'loose'(foreignObject 里跑 KaTeX)+ sanitizeMermaidSvg 消毒(load-bearing 安全件);渲染失败有 AI 修复卡(REPAIR_MERMAID)
```echarts renderEcharts echarts 默认 'dark' 主题 + 透明底,除非模型自指 backgroundColor
```markmap renderMarkmap markmap lib+view 必须 pre.replaceWith(wrapper) 先于 Markmap.create()(布局要量文本);mm.rescale() 是相对倍率,缩放走 _markmapZoomBy 绝对换算
```smiles renderSmiles RDKit MinimalLib WASM get_mol/get_rxn;RDKit 兼任校验器(化学不可能 → 显式错误条 + 保留原文);描述符行(MW/logP/TPSA…);暗色重描墨色但保 CPK 杂原子色(化学语义,禁 CSS 反色)
```pdb renderPdb Mol*(RAW 拷贝 IIFE) parsePdbBlock 分类:RCSB ID / AlphaFold AF-…-F1(经 API 解析当前版本)/ 内联坐标;applyPreset 的 representation id 必须走 representationPreset 参数;WebGL 上下文有全局 Set 跟踪并 dispose(浏览器 ~16 个上限)
```dot renderDot @viz-js/viz(WASM 内联 base64) 默认黑墨重映射 + 对比度救援;无效 DOT → 错误条 + 保留原文(无 AI 修复);模型契约:ID [label="…"] 才合法

渲染契约(教模型发什么围栏)只有一个文本源:lib/prompt-assembly.js 的 CAPABILITY_HINTS_ENTRIES——LLM/Hermes 系统通道的 CAPABILITY_HINTS 与 agent 首轮的 AGENT_RENDER_HINT 都是它的拼装,不许再出现手抄镜像(历史上 ```nn 就因镜像漏更新断供一天)。

vendor 加载与 CSP(细节见 ADR-0008 / 安全模型页)

  • 图表 vendor 懒加载 + 按需预热:preloadChartVendors() 只在真的见到围栏时触发(wantsChartVendors 嗅探,一次性门控)——无图会话不付 ~7MB 解析。
  • Mol 的 dist 永不过 esbuild*(RAW 拷贝的预构建 IIFE);RDKit/Mol* 的 embind glue 在 build.mjs 拷贝时打 CSP 补丁(new Function → 手写 invoker;eager h264 改 lazy)——补丁正则锚在稳定字符串上,molstar 升级后不匹配会让构建失败而不是静默带病。
  • 任何 vendor 更换后的验证关卡 = 真扩展加载(launchPersistentContext --load-extension,xvfb):dev-preview 是普通 http 页、默认允许 eval,验证不出 CSP 问题(2026-09-30 教训)。

资源回收

  • _chartObservers(ResizeObserver 登记)/ _renderDisposers(元素级释放)/ disposeMolstarViewers()——删除气泡、重渲历史、清空会话前都要跑;漏掉的典型症状是脱离的 WebGL 上下文永远渲染(浏览器 ~16 上限)。

源头:AGENTS.md「sidepanel.js module split」render.js/mermaid-utils/chem/dot 节、「Renderer-vendor audit」、批B/批C 不变量;ADR-0008 / 0010 / 0011。同步于 2026-10-01。

Clone this wiki locally