Files
mnote/design/old/07-ai/process/7-11-blocknote-tiptap-ai-reference-and-mnote-ai-tool-runtime-v1.md
T
lix-2026 f292c6710a feat: EditorRuntimeActor - 三层缓存/delta/事件架构
Phase A — EditorRuntimeActor 内存缓存层
- 新增 editor_actor.rs: EditorBlockDocument 内存态 + apply_command + load_or_init
- block.rs 四个写工具(replace/insert/delete/move)接入 actor 路径
- editor_actor feature flag(MNOTE_WEB_ENABLE_EDITOR_ACTOR=true 默认开启)
- bridge-runtime 三个核心函数公开化
- rust-toolchain: 1.89 → stable(修复 spike WASM 编译阻塞)

Phase B — 编辑器增量 delta channel
- BlockDelta/DeltaOperation 类型 + actor.build_block_delta()
- leptos-tiptap spike: mnote:editor:block-delta CustomEvent 监听 + JSON patch
- DocumentAiAgentPanel: 拦截 blockDelta → window dispatchEvent
- 工具响应含 blockDelta 字段供前端消费

Phase C — 事件 stream delta
- broadcast channel 在 AppState/actor/SSE 三层贯通
- tree_events SSE 端点发 block.delta 事件
- 旧客户端降级兼容

环境修复
- rustc recursion_limit = 1024(修复 Leptos SSR 类型深度溢出)
- run-convex-deploy.js(封装 Convex function 部署到本地后端 3210)

ref: design/07-ai/process/7-13-page-block-editor-runtime-actor-v1.md
2026-05-16 22:03:30 +08:00

441 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 7-11 [process][recycle] BlockNote / Tiptap AI 参考与 mnote 自有 AI 工具 runtime v1
> 更新时间:2026-05-16
>
> 当前状态:`RECYCLE`。
>
> 回收说明(2026-05-16):
> - 本稿的参考取证仍有价值,但“mnote 自有 AI 工具 runtime”口径容易误导后续实现继续扩出第二套页面 AI runtime。
> - 当前长期口径已被 `/mnt/Data1T/mnote/design/07-ai/process/7-12-page-ai-hermes-tool-routing-and-review-surface-v1.md` 覆盖。
> - 后续方向固定为:Hermes 继续作为唯一页面 AI agent runtimemnote 只建设 Hermes 可消费的工具路由、工具 manifest、上下文冻结、dry-run/review、Rust 写入校验与 readback。
> - 本稿仅作为 BlockNote / Tiptap 参考材料和历史判断保留,不再作为当前执行口径。
>
> 关联文档:
> - `/mnt/Data1T/mnote/design/07-ai/process/7-10-page-block-ai-tooling-execution-checklist-v1.md`
> - `/mnt/Data1T/mnote/design/07-ai/process/7-12-page-ai-hermes-tool-routing-and-review-surface-v1.md`
> - `/mnt/Data1T/mnote/design/07-ai/done/7-9-page-block-ai-tooling-roadmap-v1.md`
> - `/mnt/Data1T/mnote/design/07-ai/done/7-6-mnote-hermes-plugin-tool-contract-v1.md`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/done/5-13-page-block-identity-and-command-contract-v1.md`
> - `/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/blocknote-ai/MNOTE-REFERENCE.md`
---
## 1. 结论
BlockNote AI 和 Tiptap AI Toolkit 都值得参考,但参考层级不同:
- Tiptap AI Toolkit 适合作为“AI tool contract”参考:`tiptapRead``tiptapEdit``tiptapReadSelection``toolDefinitions()``executeTool/streamTool`、review options。
- BlockNote AI 适合作为“AI runtime shape”参考:`AIExtension``DocumentStateBuilder``StreamToolsProvider``AIRequest``aiMenuState``acceptChanges/rejectChanges/retry/abort`
- mnote 不能直接采用 BlockNote / Tiptap 的 editor truth。mnote 的事实源仍是 Rust kernel、Page Aggregate、EditorCommand、Convex revision/conflict key 与 Hermes audit。
下一步不应把 BlockNote 重新拉回运行时主链,也不应把 Tiptap Pro / BlockNote XL AI 当成硬依赖。正确方向是用它们的架构形态,打造 mnote 自己的 Rust-owned AI tool runtime。
---
## 2. 已拉取参考代码
已将 BlockNote 官方仓库以 sparse clone 方式拉到:
`/mnt/Data1T/mnote/design/05-editor-mainline/reference-code/blocknote-ai/`
当前提交:
`c255558b2d4f2be6453c67df81bb702a1a586909`
保留范围:
- `docs/content/docs/features/ai/`
- `examples/09-ai/`
- `packages/xl-ai/src/`
- `packages/xl-ai-server/src/`
- 对应 `package.json` / `LICENSE`
许可证边界:
- `@blocknote/xl-ai` 当前标注为 `GPL-3.0 OR PROPRIETARY`
- 本目录只能作为 `reference-code` 研究材料。
- 不允许未审查许可证就复制实现进入 mnote runtime。
---
## 3. BlockNote AI 可借鉴能力
### 3.1 AI lifecycle 状态机
参考:
- `reference-code/blocknote-ai/packages/xl-ai/src/AIExtension.ts`
BlockNote 的 AI menu state 包含:
```text
closed
user-input
thinking
ai-writing
user-reviewing
error
```
并提供:
- `openAIMenuAtBlock(blockId)`
- `closeAIMenu()`
- `invokeAI(opts)`
- `acceptChanges()`
- `rejectChanges()`
- `retry()`
- `abort(reason)`
- `setAIResponseStatus(...)`
mnote 应吸收为:
- `PageAIController`
- `PageAIRunState`
- `PageAIReviewSession`
但状态源必须绑定 mnote 的 `documentId/workspaceId/blockId/revision/conflictDetectionKey`,不能绑定 BlockNote editor instance。
### 3.2 DocumentStateBuilder
参考:
- `reference-code/blocknote-ai/packages/xl-ai/src/api/formats/DocumentStateBuilder.ts`
- `reference-code/blocknote-ai/packages/xl-ai/src/api/aiRequest/builder.ts`
BlockNote 把 AI 上下文拆成两种:
- 无选区:全量 document blocks + cursor position。
- 有选区:selected blocks + whole document context;模型只能对 selection 发操作。
mnote 应吸收为 `PageAIContextBuilder`
```json
{
"schema": "mnote.page_ai_context.v1",
"workspaceId": "tree_x",
"documentId": "tree_y",
"runId": "run_1",
"scope": "selection",
"revision": 12,
"conflictDetectionKey": "body:...",
"selectedBlocks": [],
"contextBlocks": [],
"allowedTargetBlockIds": []
}
```
约束:
- context 必须从 Page Aggregate block projection 生成。
- selection 必须在 AI run 开始时冻结,不能随用户后续选区漂移。
- `allowedTargetBlockIds` 必须作为写工具校验输入的一部分。
### 3.3 StreamToolsProvider
参考:
- `reference-code/blocknote-ai/packages/xl-ai/src/api/formats/formats.ts`
- `reference-code/blocknote-ai/packages/xl-ai/src/api/formats/base-tools/`
- `reference-code/blocknote-ai/packages/xl-ai/src/streamTool/`
BlockNote 的 stream tool 把 add/update/delete block 建模为 schema + validate + executor。
mnote 已有对应底座:
- `mnote.doc.fetch`
- `mnote.doc.find`
- `mnote.block.fetch`
- `mnote.doc.plan_update`
- `mnote.block.replace`
- `mnote.block.insert_after`
- `mnote.block.delete`
- `mnote.block.move_after`
- `mnote.doc.apply_block_ops`
mnote 下一步要补的不是工具名,而是工具 manifest 的能力注解:
```json
{
"name": "mnote.block.replace",
"annotations": {
"readonly": false,
"destructive": false,
"idempotent": false,
"requiresApproval": true,
"selectionEffect": "destroy",
"runtimeOwner": "mnote-web",
"writeOwner": "rust-runtime-kernel"
}
}
```
### 3.4 Review / accept / reject
参考:
- `reference-code/blocknote-ai/packages/xl-ai/src/AIExtension.ts`
- `reference-code/blocknote-ai/packages/xl-ai/src/prosemirror/rebaseTool.ts`
- `reference-code/tiptap-docs/src/content/content-ai/capabilities/ai-toolkit/api-reference/review-options.mdx`
BlockNote 在 editor 内通过 suggestions / fork ydoc 完成 reviewTiptap AI Toolkit 则提供 `review/preview/trackedChanges` 模式。
mnote 不能照搬 ProseMirror suggestion 作为事实源。mnote 应建立自己的 review session
```json
{
"schema": "mnote.page_ai_review_session.v1",
"reviewSessionId": "review_1",
"runId": "run_1",
"documentId": "tree_y",
"workspaceId": "tree_x",
"status": "previewing",
"baseRevision": 12,
"baseConflictDetectionKey": "body:...",
"operations": [],
"diff": [],
"warnings": [],
"risk": "low"
}
```
状态:
```text
draft
planning
previewing
awaiting_user
accepted
rejected
applying
applied
failed
aborted
stale
```
写入规则:
- AI 写工具默认先生成 review session。
- 用户 accept 后才执行 `mnote.doc.apply_block_ops` 或单个 `mnote.block.*`
- accept 时重新校验 `revision/conflictDetectionKey/revisionRef`
- reject 只关闭 session,不改变正文。
---
## 4. Tiptap AI Toolkit 可借鉴能力
Tiptap AI Toolkit 已在 `7-9` 中完成第一轮映射,本文补充它与 BlockNote 的组合边界。
| Tiptap / BlockNote 能力 | mnote 对应 | 吸收内容 | 禁止吸收 |
| --- | --- | --- | --- |
| `tiptapRead` | `mnote.doc.fetch` / `mnote.block.fetch` | 先读、带范围、返回 AI 友好表示 | 不把 Tiptap JSON 当长期工具格式 |
| `tiptapEdit` | `mnote.doc.plan_update` + `mnote.block.*` | 操作列表、dry-run、diff、reviewable edit | 不让浏览器 editor command 成为事实源 |
| `tiptapReadSelection` | `mnote.doc.fetch scope=selection` | selection-aware workflow | 不持久化 ProseMirror selection range |
| `toolDefinitions()` | Rust Hermes manifest | schema、description、capability、annotations | 不依赖私有 npm 包 |
| `AIExtension` | `PageAIController` | AI lifecycle、menu state、abort/retry | 不引入 BlockNote runtime |
| `DocumentStateBuilder` | `PageAIContextBuilder` | selection/context 分离 | 不从 DOM 拼上下文 |
| `StreamToolsProvider` | `MnoteAIToolProvider` | 工具集合按能力开放 | 不在前端直接执行正式持久化 |
| `acceptChanges/rejectChanges` | `PageAIReviewSession` | preview -> accept/reject | 不以 ProseMirror suggestion 作为最终事实 |
---
## 5. mnote 自有 AI runtime 设计
### 5.1 分层
```text
Page Aggregate / Rust kernel
-> PageAIContextBuilder
-> MnoteAIToolProvider
-> Hermes / model runtime
-> PageAIReviewSession
-> EditorCommand / page.body.save
-> Page Aggregate 回读验证
```
### 5.2 组件职责
`PageAIContextBuilder`
- 输入:`workspaceId/documentId/scope/selection/blockId/query/maxBlocks`
- 输出:`mnote.page_ai_context.v1`
- 数据源:Page Aggregate block projection。
- 负责 selection 冻结、上下文裁剪、`allowedTargetBlockIds`
`MnoteAIToolProvider`
- 输入:profile、document capability、selection scope、feature flags。
- 输出:可用工具 manifest。
- 负责 `readonly/destructive/requiresApproval/selectionEffect` 等注解。
`PageAIController`
- 管理当前页面 AI run。
- 对齐状态:`user-input/thinking/ai-writing/user-reviewing/error/aborted`
- 不直接写正文,只组织 context、tool calls、review session。
`PageAIReviewSession`
- 保存 plan/diff/warnings/risk/operations。
- 提供 `accept/reject/retry/abort`
- accept 时走 Rust 写工具,并二次校验 revision。
`PageAIReviewSurface`
- 页面内展示 AI 结果、工具卡、diff、风险、按钮。
- 不把 tool result 当正文。
- 不绕过 review session 调写工具。
---
## 6. 格式策略
当前 mnote 不能把 HTML 作为长期 AI contract。推荐格式分三层:
`json`
- 面向工具执行。
- 保留 block id、type、attrs、children、revisionRef。
- 作为写工具输入和回读校验主格式。
`text`
- 面向摘要、问答、轻量改写。
- 不可直接作为精确写入定位依据。
`page_xml`
- 面向模型理解结构。
- 形态示例:
```xml
<page id="tree_y" revision="12">
<block id="p_1" type="paragraph" revisionRef="body:12:p_1">第一段</block>
<block id="h_1" type="heading" level="2" revisionRef="body:12:h_1">标题</block>
</page>
```
约束:
- `page_xml` 只能是 Page Aggregate projection 的序列化视图。
- 写入仍必须转成 `mnote.block.*``mnote.doc.apply_block_ops`
---
## 7. 执行 checklist
### Phase A:参考口径冻结
- [x] 拉取 BlockNote AI sparse reference 到 `reference-code/blocknote-ai/`
- [x] 标注来源 commit 与许可证边界。
- [x] 明确 BlockNote 只作为 AI runtime shape 参考,不作为 mnote runtime dependency。
- [x] 明确 Tiptap AI Toolkit 只作为 tool contract 参考,不作为事实源。
### Phase BPageAIContextBuilder
- [x] 定义 `mnote.page_ai_context.v1` schema。
- [x] `doc.fetch` 支持 `scope=selection`
- [x] selection run 开始时冻结 `selectedBlockIds` / `allowedTargetBlockIds`
- [x] `doc.fetch` 支持 `format=text/page_xml/json`
- [x] `block.fetch` 支持 `format=text/page_xml/json`
- [ ] 大页面 context 默认裁剪,返回 `truncated/warnings/continuation`
验收:
- [ ] AI run 期间用户改变选区,不影响本 run 的 selection context。
- [ ] 写工具不能修改 `allowedTargetBlockIds` 外的块。
- [ ] `page_xml` 与 JSON projection 的 block id / revisionRef 一致。
### Phase CMnoteAIToolProvider
- [x] tool manifest 增加 `annotations`
- [x] 当前 yolo 模式下写工具标注 `requiresApproval=false` / `approvalMode=yolo`
- [x] selection scope 下,写工具自动带 `allowedTargetBlockIds` 约束。
- [ ] profile tool toggle 与 capability annotation 同时生效。
- [ ] manifest 输出能直接转换给 Hermes/model runtime。
验收:
- [ ] 禁用工具不出现在当前 AI run 的可用工具集中。
- [ ] 复杂块工具返回 `unsupportedReason`,不伪装成可编辑。
- [ ] manifest 能说明工具是否 destructive / readonly / requiresApproval。
### Phase DPageAIReviewSession
- [ ] 定义 `mnote.page_ai_review_session.v1`
- [ ] `mnote.doc.plan_update` 可创建 review session。
- [ ] `mnote.doc.apply_block_ops dryRun=true` 可返回 review session draft。
- [ ] 页面 AI UI 展示 diff、warnings、risk、blocked。
- [ ] `accept` 执行写入前二次校验 revision/conflictDetectionKey/revisionRef。
- [ ] `reject` 不改变正文。
- [ ] `abort` 停止 run,关闭未提交 review session。
- [ ] `retry` 使用最新 Page Aggregate 重新构建 context。
验收:
- [ ] accept 后 Page Aggregate 与 `mnote.doc.fetch` 都能读回变化。
- [ ] stale revision 时 accept 被阻断,session 进入 `stale`
- [ ] reject 后页面正文、revision、block ids 不变化。
### Phase E:页面 AI 状态机
- [ ] 实现 `PageAIController` 状态枚举。
- [ ] AI menu / side panel 共享同一 run state。
- [ ] tool event 按 `toolCallId` 聚合展示。
- [ ] 错误态支持 retry / close。
- [ ] abort 态不会留下半写入正文。
验收:
- [ ] `thinking -> ai-writing -> user-reviewing -> accepted/rejected` 链路可见。
- [ ] 网络失败、tool parse 失败、revision stale 三类错误可区分。
- [ ] 页面刷新后未提交 review session 不会自动写入正文。
---
## 8. 当前优先级
优先级顺序:
1. `PageAIContextBuilder + scope=selection`
2. `format=page_xml/text`
3. `PageAIReviewSession`(后续可选 review 模式;当前默认 yolo 不阻塞写入)
4. `PageAIController` 状态机与 UI surface
5. 复杂块移动 / 删除 / 多块操作阻断矩阵
原因:
- selection 和 context 是 AI 质量与安全边界的前置条件。
- `page_xml/text` 能降低模型误读 projection 的概率。
- review session 是生产写入前必须补齐的用户确认层。
- 状态机和 UI surface 应建立在稳定 session 语义之上。
---
## 9. 禁止项
- 不把 BlockNote 重新设为文档页默认主编辑器。
- 不把 `@blocknote/xl-ai` 作为 mnote runtime dependency。
- 不复制 GPL/PROPRIETARY 源码进入 mnote 运行时代码。
- 不让前端 editor instance 直接执行长期持久化写入。
- 不以 HTML / Tiptap JSON / ProseMirror position 作为 mnote 长期 AI tool contract。
- 不绕过 `dryRun/idempotencyKey/revision/conflictDetectionKey/revisionRef` 执行 AI 写工具。
---
## 10. 与 `7-10` 的关系
`7-10` 继续作为页面块 AI 工具执行 checklist。
本文补充的是 `7-10` 后半段缺口的架构口径:
- `scope=selection`
- `format=page_xml/text`
- `持久审阅/preview UI`
- `AI lifecycle 状态机`
- `accept/reject/retry/abort`
因此本文不替代 `7-10`,而是作为下一阶段 AI runtime 收口设计稿。