- 产品层:产品宪章与永久禁域、产品定义、完整 1.0 范围与发布门、道家文化语言体系、指标与反指标 - 研究层:参考项目研究(deepseek-harness、pi、MemOS、模型网关)、灵台原生引擎研究(业界原生引擎架构理念与道家文化出处) - 架构层:系统、Agent 运行时(周天体系)、插件系统、灵台引擎(C++ 双形态)、媒体与设备、社区协作市场、前端富内容渲染、数据、记忆与知识 - 契约层:协议与稳定标识、API 总体约定、Native API、兼容网关、实时与 Webhook、内部端口、统一 ContentBlock 与流式(含分支对话交互态)、灵台 C ABI 与 gRPC Service、API 表面、HTTP 与事件、运行观测 - 决策:ADR-001 至 ADR-023(模块化单体、每 attempt 持久化、候选记忆、OAuth 2.1、灵台引擎、双形态部署、大周天演化、宪章、三界作用域、私箧与保全态、叩心、周天统一等) - 交付:WP-01 至 WP-15 实施 TODO 与设计阶段交接文档 - 工程:AGENTS.md 工程规则(含 C++/灵台规范)、CLAUDE.md 引用、.gitignore
8.6 KiB
8.6 KiB
前端富内容实时渲染
1. 适用客户端
同一渲染内核服务 Next.js Web、Tauri Desktop 和 Tauri Mobile。平台差异只位于资源加载、文件保存、设备能力和性能档位;ContentBlock 与流状态机保持一致。
推荐组件:
- Markdown:
react-markdown+remark-gfm+ 受控 remark/rehype 插件; - Code:Shiki,高亮 Worker 与缓存;
- Math:KaTeX 为默认,MathJax 只作为兼容回退;
- Mermaid:Mermaid strict mode,在 Worker/隔离容器渲染 SVG;
- 长列表:
@tanstack/react-virtual; - 媒体:原生 image/video/audio,使用受控资源 URL;
- 状态:TanStack Query 管服务端资源;轻量本地 store 管流 accumulator 和 UI 状态。
新增依赖前仍需按 AGENTS.md 查当前维护状态和已安装能力。
2. 渲染流水线
flowchart LR
SSE[SSE Events] --> ACC[Event Accumulator]
ACC --> STORE[Block Store]
STORE --> PARSE[Incremental Parse]
PARSE --> SAFE[Sanitize and Validate]
SAFE --> RENDER[Typed Renderers]
RENDER --> DOM[Accessible UI]
FINAL[Completed Message] --> RECON[Reconcile]
RECON --> STORE
各层职责:
- Event Accumulator:校验 run sequence 与 block delta index,去重和检测缺口。
- Block Store:以
message_id/block_id保存原始 block、流状态和 renderer 状态。 - Parse:只对允许增量的类型做节流解析。
- Sanitize:URL、Markdown AST、SVG、公式和媒体元数据安全处理。
- Renderer:按 Block type 分派,未知类型显示兼容占位而不崩溃。
- Reconcile:
content.block.completed与message.completed到达后用权威快照替换临时状态。
3. 流状态机
stateDiagram-v2
[*] --> pending
pending --> streaming : block.started
streaming --> streaming : ordered delta
streaming --> awaiting_replay : delta gap
awaiting_replay --> streaming : replay filled
awaiting_replay --> completed : final snapshot
streaming --> completed : block.completed
streaming --> failed : block.failed
streaming --> cancelled : block.cancelled
failed --> completed : retry/resource ready
completed --> [*]
cancelled --> [*]
- 乱序 delta 暂存在小窗口;超过窗口请求重放,不猜顺序。
- 重复 delta 根据
(block_id, delta_index)丢弃。 - 连接断开保留乐观内容并标记“正在恢复”;最终 GET Run/Message 对账。
- Final snapshot 与累积 hash 不一致时记录前端诊断并以服务端快照为准。
4. Markdown 增量渲染
4.1 策略
- 原始增量文本始终保留;AST 是可丢弃派生状态。
- 以 50–100 ms 或换行边界节流解析,不逐 token 全量重渲染。
- 未闭合 fence、链接、表格、强调或数学定界符保持源码/纯文本展示,不自动补造语义。
- Completed 后对完整 Markdown 再解析一次,替换临时 AST。
- 大 Block 分段渲染,避免每次 delta 重建整个消息树。
4.2 安全
- 禁用原始 HTML;若以后开放,仅对可信内部内容使用严格 allowlist。
- 链接协议允许
https、mailto和内部资源 scheme;拒绝javascript、危险data、file。 - 外链打开使用
noopener noreferrer,并显示目标域。 - Markdown 图片规范化为 Image Block;不直接加载任意第三方跟踪像素。
5. Code 与 Shiki
- 流式时先用等宽纯文本展示;完整行或节流窗口后发送 Worker 高亮。
- Shiki grammar 按需加载并缓存;未知语言回退 plain text。
- 超大代码块关闭实时高亮,完成后按可见区域高亮。
- 提供复制、换行、下载、语言、文件名和行号;复制取原始源码,不从高亮 DOM 提取。
- 代码永不在渲染器执行;可执行动作是独立 Tool/Approval。
6. 数学公式
6.1 解析
- Native Math Block 直接按
notation处理。 - Markdown 中只有闭合
$...$、$$...$$、\(...\)、\[...\]才触发公式渲染。 - 流式未闭合公式显示转义源码和稳定占位,避免页面反复跳动。
- KaTeX 解析失败显示
fallback_text或源码,并提供错误详情展开。
6.2 安全和可访问性
- KaTeX
trust=false,限制宏、展开深度和输入长度;禁用 URL/HTML 注入命令。 - 生成 MathML/ARIA;Block 公式提供自然语言
fallback_text、变量和单位说明。 - 用户可切换“渲染公式/显示源码”。
- 常见公式描述采用“名称 → 公式 → 变量/单位 → 适用条件 → 示例”的结构,不把推导过程混入隐藏思维。
7. Mermaid
- 流式期间不渲染图,仅展示代码骨架和进度。
block.completed后把源码发送 Worker;验证节点数、边数、字符数和超时。- Mermaid 使用
securityLevel: strict,禁止 click、HTML label、外部资源和任意初始化指令。 - 输出 SVG 再经 sanitizer;SVG 不允许 script、foreignObject、事件属性或外部 URL。
- 渲染失败显示源码、错误摘要和“复制到 Mermaid 编辑器”的安全动作,不空白。
- 提供缩放、平移、适配宽度、下载 SVG/PNG、文本替代和全屏。
- 图表在移动端默认源码/缩略图折叠,按需展开,防止长宽溢出。
8. 图片、视频和音频
图片
- 使用
file_id换取短期授权 URL;响应式尺寸、懒加载、占位、失败重试和 alt。 - 不信任服务端文件名/MIME;资源域返回正确 Content-Type、CSP、CORP 和
nosniff。 - 大图支持查看器、缩放和下载;不默认将 EXIF 暴露给其他用户。
视频
- 等待
resource_ready后显示 poster;使用 HLS/DASH 或受控 MP4。 - 提供字幕、转写、时长、加载/转码状态和失败说明。
- 自动播放默认关闭;有声音播放必须由用户手势触发。
音频
- 显示波形/时长/转写;流式 TTS 与固化 Audio Block 分离。
- 实时语音使用 WebSocket 播放队列,不把每帧写入 React 树。
- 支持打断、静音、速度和字幕;停止后清空未播放帧。
9. Agent、工具和审批展示
- AgentStatus Block 显示当前阶段、ChildRun、预算、等待和取消操作,不展示隐藏推理。
- ToolCall Block 默认显示工具名、用途、状态、耗时和脱敏参数摘要;敏感详情走诊断授权。
- ApprovalRequest 必须显示动作、目标、影响、费用、数据范围、有效期、允许/拒绝按钮。
- ToolResult 区分成功、错误、未知结果和产物,不把错误结果渲染成普通助手文本。
- 并行 ChildRun 使用树/时间线,主消息流只展示汇总状态,避免刷屏。
10. 长列表与性能
- Conversation/Community/Diagnostics 使用虚拟滚动,Block 高度由 ResizeObserver 缓存。
- 流式中的当前 Message 可脱离虚拟列表单独渲染,完成后归档入列表。
- Markdown AST、Shiki tokens、Mermaid SVG 和 Math 渲染按 content hash 缓存。
- Worker 处理高亮、Mermaid 和重解析;主线程只提交最终安全树。
prefers-reduced-motion关闭非必要动画;流式光标不引发布局抖动。- 建立不同设备性能档:关闭实时代码高亮、降低 Avatar 帧率、延迟复杂图渲染,而不丢失内容。
11. 可访问性
- 每个 Block 使用正确语义元素和可聚焦操作。
- 新 delta 不持续抢夺屏幕阅读器焦点;用节流
aria-live汇报状态。 - 图像必有 alt;图表有 title/caption/源码替代;音视频有字幕/转写。
- 数学提供 MathML 和 fallback text;代码支持键盘复制和横向滚动。
- 工具确认、错误和费用不能只靠颜色表达。
- Avatar/动效不阻塞核心内容和操作。
12. 失败与降级
| 失败 | 展示 |
|---|---|
| Markdown 解析失败 | 转义纯文本 |
| Shiki 失败 | plain code |
| Math 失败 | fallback text + source |
| Mermaid 失败 | source + error summary |
| 媒体未就绪 | progress placeholder |
| 媒体失败 | retry/download details |
| 未知 Block type | “当前客户端暂不支持” + JSON-safe summary |
| SSE 断线 | recovering 状态 + replay/final fetch |
| hash 不一致 | final snapshot + diagnostic marker |
降级必须保留用户内容,不以空白、崩溃或静默删除处理。
13. 测试
- 对每种 Block 建立 canonical fixture、流式分片、断线、重复、乱序、失败和未知类型测试。
- Markdown/Math/Mermaid 做 XSS、URL、SVG、宏膨胀和资源耗尽测试。
- 浏览器组件测试覆盖键盘、屏幕阅读器、reduced motion 和移动布局。
- Playwright 覆盖从 SSE 到 Markdown/公式/Mermaid/媒体/Tool Approval 的端到端流程。
- 对 1 MB Markdown、万行代码、复杂 Mermaid、长公式和大量消息做性能基线。