Files
mnote/design/07-ai/done/7-42-page-ai-mindmap-skill-and-resource-generation-v1.md
T
lix-2026 1882db7681 收口 MNote P0 P1 P2 审查尾项
- 归档 OnlyOffice live bridge、Page AI、mindmap、design governance 与相关 bug 条目
- 补齐 MinerU OCR 后端 runtime 合同与 smoke/test 基线
- 收口 ChatOnly/Doubao、ObjectIdentity、Page Aggregate compat 与 runtime owner 文档口径

验证:
- cargo test --manifest-path rust/Cargo.toml -p mnote-web local_ocr -- --test-threads=1
- cargo test --manifest-path rust/Cargo.toml -p mnote-web onlyoffice_bridge -- --test-threads=1
- git diff --check
- git diff --cached --check
- codegraph index . --force && codegraph status .
- codegraph sync . && codegraph status .
2026-06-01 09:29:12 +08:00

408 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-42 Page AI mindmap skill and resource generation v1
> 创建时间:2026-05-30
> 状态:`done`
> owner`07-ai`
> 上位参考:
> - `design/07-ai/reference/7-28-resource-ai-tool-contract-v1.md`
> - `design/07-ai/done/7-3-page-ai-hermes-panel-and-mnote-plugin-v1.md`
> - `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md`
> - `design/04-tree-domain/done/4-24-resource-tree-filetree-pagetree-source-contract-checklist-v1.md`
## 1. 背景
当前 Page AI 的 MNote 内置技能只有:
- `mnote-current-page`
- `mnote-local-file`
- `mnote-chat-only`
但 Rust Hermes tool manifest 已经暴露了资源工具雏形:
- `mnote.mindmap.fetch`
- `mnote.mindmap.apply_ops`
这说明底层 resource tool 方向已经存在,缺口不在“完全没有工具”,而在 Page AI 缺少一个明确的 `mnote-mindmap` 内置 skill 来指导 agent 何时读取、何时写入、如何生成新的思维导图资源,以及如何把 PDF / Office / Markdown 等材料整理成新的 `.mindmap.json`
用户明确的长期目标是:
> AI 能总结 PDF,并整理新建出思维导图。
因此本设计不能只覆盖“编辑已有导图节点”,还必须覆盖“从外部材料生成新导图资源”的闭环。
## 2. 原型观察
### 2.1 KMind plugin
`reference-code/kmind-plugin` 体现的关键点:
-`simple-mind-map` 风格树结构为核心。
- 支持多根、MOC、文档树导图、节点超链接、TODO、主题、布局、导入导出。
- 节点可以携带思源块/文档引用,说明 mindmap 节点不只是纯文本,还可能是资源引用容器。
- 导入导出会处理 markdown、Freemind、XMind 等格式,但最终仍要落回 mindmap runtime 可消费的数据结构。
对 MNote 的启发:
- AI 不能把思维导图降级为普通 Markdown 大纲后直接覆盖文件。
- AI 写入必须尽量保留未知扩展字段,如节点样式、引用、视图状态、主题配置。
- 从 PDF 生成导图时,应先生成结构化 outline,再转换成 mindmap tree,而不是让模型手写完整 runtime JSON。
### 2.2 lx-doc mind-map
`reference-code/lx-doc/mind-map` 体现的关键点:
- 思维导图项目独立部署,工作台只负责文件/资源管理。
- 文件内容是完整对象,典型形态为:
- `root`
- `theme`
- `layout`
- `config`
- `view`
- runtime 使用 `setFullData` 恢复完整文件,用 `getData(true)` 保存全量配置。
- `root``simple-mind-map` 树:`{ data: { text, uid, ... }, children: [...] }`
对 MNote 的启发:
- mindmap 是 Resource Tree 对象,不是 Markdown 正文的一部分。
- Markdown 页面只保留占位、链接或嵌入引用。
- AI 读写 mindmap 时应围绕 resource 文件、object identity 和 resource capability 工作。
## 3. 当前 MNote 数据合同
当前默认 `.mindmap.json` 不是裸树,而是 envelope
```json
{
"data": {
"children": [],
"data": {
"expand": true,
"isActive": false,
"text": "KMIND",
"uid": "root"
}
},
"view": {
"state": {
"scale": 1,
"sx": 0,
"sy": 0,
"x": -44.99991989135742,
"y": -15.500006675720217
},
"transform": {
"a": 1,
"b": 0,
"c": 0,
"d": 1,
"e": -44.99991989135742,
"f": -15.500006675720217,
"originX": 0,
"originY": 0,
"rotate": 0,
"scaleX": 1,
"scaleY": 1,
"shear": 0,
"translateX": -44.99991989135742,
"translateY": -15.500006675720217
}
}
}
```
设计约束:
- 最终写入文件必须保持 envelope。
- 根节点位于 `data.data`
- 子节点位于 `data.children`
- 新建导图默认 `data.data.uid``root`
- 新建导图默认 `data.data.text` 可由用户材料标题覆盖;没有标题时使用 `KMIND`
- `view` 默认使用上述稳定模板;AI 不应自行发明缩放和位移。
- 修改已有导图时必须保留未知字段,包括 `view`、节点样式、节点引用、主题和未来扩展字段。
## 4. 目标
- 新增 Page AI MNote 内置 skill`mnote-mindmap`
- 让 Hermes / Reasonix 在 Page AI 中知道如何读写当前页面或当前资源 tab 的 mindmap。
- 让 AI 能从 PDF、Office、Markdown、当前页内容或用户粘贴文本生成层级 outline,再创建新的 mindmap resource。
- 让新建导图进入 Resource Tree / File Tree / Page Tree 的正确边界,而不是写进 Markdown 正文。
- 保留 local-first 主线:本地 `.mindmap.json` 是本地导图资源真相;Rust control-plane 负责授权、审计和 resource identity。
## 5. 非目标
- 不在本批实现 PDF OCR / MinerU / Office 文本抽取本身。
- 不把 mindmap 正文存进 Markdown 页面。
- 不让 Page AI 前端私有拼第二套 mindmap 真相。
- 不让 agent 直接大段重写完整 JSON 作为默认写入方式。
- 不引入轮询刷新链路;写入后的 UI 同步应走已有 watcher、resource session 或命令结果驱动刷新。
## 6. Skill 设计
新增内置 skill
```text
id: mnote-mindmap
title: MNote mindmap editing
description: Read, update, summarize, or create MNote mindmap resources, including generating a new mindmap from PDF or document outlines.
agentIds: hermes, reasonix
readOnly: false
requiresContextRefs: current_page, file, folder, resource
toolNames:
- mnote.context.snapshot
- mnote.context.resolve_target
- mnote.mindmap.fetch
- mnote.mindmap.apply_ops
- mnote.mindmap.create_from_outline
```
Skill 正文规则:
- 只有用户明确要求“思维导图 / mindmap / KMind / 脑图 / 从材料生成导图”时启用。
- 先解析目标资源,再读取内容。
- 若当前 Page AI target 是 mindmap resource tab,优先使用该资源。
- 若当前页面包含 mindmap embed,占位中的 `mindmapId` / `sourcePath` 是候选资源。
- 若用户要求“从 PDF 生成导图”,先读取或请求 PDF 摘要/outline,再调用 mindmap 创建工具。
- 写前必须确认 `permissionLevel=read_write`,并确认 `allowedResourceIds` 覆盖目标资源。
- 写后必须回读,并报告新建或变更的 `.mindmap.json`
- 生成 outline 时必须使用“中心主题 + 一级分类 + 短语化节点”的导图结构;禁止把 PDF/文档摘要以长段落塞进节点文本。
- 节点文本优先使用关键词或短语,一个节点只表达一个概念;层级必须用 `children` 表达,引用/页码/来源信息优先放入 `sourceRefs` 或 metadata。
## 7. Tool 面设计
### 7.1 `mnote.mindmap.fetch`
保留现有命名,增强返回结构。
输入:
- `workspaceId`
- `documentId`
- `mindmapId`
- `rootUri`
- `resourcePath`
- `scope`: `tree | subtree | markdown_summary | full_envelope`
- `nodeId`
- `aiAccessScope`
输出:
- `objectIdentity`
- `resourceKind=mindmap`
- `mindmapId`
- `resourcePath`
- `revision`
- `envelope`,仅 `full_envelope` 返回
- `root`
- `nodes`
- `edges`
- `markdownSummary`
- `source=local_folder`
约束:
- `tree` / `markdown_summary` 默认不返回完整 envelope,避免 prompt 被视图和样式噪音污染。
- `full_envelope` 只在需要保留或精确 patch 文件时使用。
### 7.2 `mnote.mindmap.apply_ops`
当前该工具已存在,但 local resource 非 dry-run 仍提示 agent 用原生 patch。后续应收口为真正结构化写入工具。
输入:
- `workspaceId`
- `documentId`
- `mindmapId`
- `rootUri`
- `resourcePath`
- `expectedRevision`
- `ops`
- `aiAccessScope`
建议 ops
- `updateText`
- `insertChild`
- `insertSiblingAfter`
- `deleteNode`
- `setHyperlink`
- `setRefs`
- `appendNote`
- `patchView`
- `setLayout`
- `setTheme`
约束:
- 默认只改 `data` 树和指定 metadata。
- 未知字段必须透传。
- `expectedRevision` 不匹配时拒写或返回 conflict。
- 写入后返回 `revision``changedFiles``markdownSummary`
### 7.3 `mnote.mindmap.create_from_outline`
新增工具,用于“从材料生成新导图”。
输入:
- `workspaceId`
- `documentId`
- `rootUri`
- `targetPageId``targetDocumentId`
- `resourcePath`,可选;缺省由服务端生成唯一 `.mindmap.json`
- `title`
- `outline`
- `sourceRefs`
- `aiAccessScope`
- `embedIntoPage`,默认 `true`
`outline` 建议格式:
```json
[
{
"text": "一级主题",
"children": [
{
"text": "二级主题",
"children": []
}
]
}
]
```
输出:
- `objectIdentity`
- `mindmapId`
- `resourcePath`
- `envelope`
- `revision`
- `changedFiles`
- `embedResult`
- `markdownSummary`
写入规则:
- 服务端负责把 outline 转换为默认 envelope。
- 根节点文本使用 `title`,没有标题时使用 `KMIND`
- 子节点 uid 由服务端稳定生成,避免模型生成重复 uid。
- 默认 view 使用当前稳定模板。
-`embedIntoPage=true`,通过 Resource Tree / Markdown embed 合同把资源绑定到当前页面。
## 8. PDF 到导图闭环
长期目标链路:
```text
PDF resource
-> 文本/OCR/章节提取
-> AI 生成层级 outline
-> mnote.mindmap.create_from_outline
-> 写入 .mindmap.json
-> Resource Tree 绑定当前页面
-> 打开 mindmap resource tab
```
本设计只冻结后半段合同:
- PDF 摘要工具输出应是 `title + outline + sourceRefs`
- `sourceRefs` 可以记录 PDF 文件、页码、章节、引用片段。
- mindmap 节点可把 `sourceRefs` 保存到节点 `refs``note`,但第一版只要求保留到工具审计和 root metadata。
后续可接入:
- `mnote.office.fetch_summary`
- `mnote.pdf.extract_outline`
- MinerU markdown 识别结果
- 本地 Markdown / 当前页正文
## 9. 权限与审计
读写 mindmap resource 必须同时满足:
- 当前 actor 拥有 root 的 read 或 write grant。
- `aiAccessScope.permissionLevel` 覆盖目标操作。
- `allowedResourceIds` 包含 `mindmapId``resourcePath``objectIdentity`
- 写入只能落在授权 root 内。
审计必须记录:
- tool name
- sessionId / runId / traceId
- actorId
- documentId
- mindmapId
- resourcePath
- sourceRefs
- changedFiles
- before / after revision
## 10. Page AI 上下文
Page AI run payload 应能携带当前 mindmap target
```json
{
"contextRefs": [
{
"kind": "resource",
"resourceKind": "mindmap",
"objectIdentity": "resource:mindmap:{documentId}:{mindmapId}",
"documentId": "{documentId}",
"mindmapId": "{mindmapId}",
"resourcePath": "{relativePath}",
"rootUri": "{rootUri}"
}
]
}
```
来源优先级:
1. 当前打开的 mindmap resource tab。
2. 当前页面选中的 mindmap block/embed。
3. 当前页面中唯一 mindmap embed。
4. 用户明确给出的资源文件路径。
5. 创建新导图时,当前页面作为目标页面。
## 11. 验收清单
- [x] MNote 内置技能面板出现 `MNote mindmap editing`
- [x] `mnote-mindmap` 开关能进入 `skillPreferences.mnote`
- [x] `mnote.skill.read` 能读取 `mnote-mindmap` 正文。
- [x] `mnote-mindmap` 正文说明导图 outline 格式:中心主题、一级分类、短语化节点、避免长段落。
- [x] `mnote.mindmap.fetch` 可读取默认 envelope 并返回 root/nodes/summary。
- [x] `mnote.mindmap.create_from_outline` 可生成符合默认 envelope 的 `.mindmap.json`
- [x] `mnote.mindmap.create_from_outline` 在显式 `embedIntoPage=true` 时可把新导图链接写入当前 local-md 页面。
- [x] `task503-mindmap-skill-capability-smoke` 可直接读取 skill、创建能力导图、fetch 回读、绑定当前页面,并用真实登录浏览器截图验证。
- [x] 新建导图能绑定当前页面并在 File Tree / Resource Tab 可见。
- [x] `mnote.mindmap.apply_ops` 写入后保留 `view` 和未知字段。
- [x] shared/read-only scope 下写工具拒绝。
- [x] revision 不匹配时拒写或返回 conflict。
- [x] PDF outline fixture 可生成 mindmap resource。
- [x] 真实 mindmap resource tab 能注入 Page AI `active_editor` contextRef / `targetPackage`
当前第一批已完成 Page AI skill 发现、skill 正文读取、默认 envelope fetch、`create_from_outline` 写入、显式 `embedIntoPage=true` 页面链接绑定、`task502` Page AI skill payload smoke,以及 `task503` 直接 tool 创建导图 + 页面绑定 + 浏览器截图 smoke。第二批已完成 `apply_ops` 最小结构化写入、`view` / 未知字段保留、revision conflict 和 shared/read-only 拒写单测;2026-06-01 已修复 `task455` 暴露的 local-folder embedded mindmap 刷新后 id 退化,根因是 `blockDocument.blocks[].attrs` 未保留 `mindmapId/sourcePath/rootNodeId` 且浏览器 conversion 未读取 blockDocument attrs;新增 `task525` 覆盖真实 mindmap resource tab 的 Page AI `active_editor` contextRef / `targetPackage`
2026-06-01 复核:`mnote.mindmap.apply_ops` 已从 native patch 提示收口到最小结构化写入,当前支持 `updateText` / `updateNode``insertChild` / `addChild``deleteNode`,并由 `hermes_tools_mindmap_apply_ops_writes_and_preserves_envelope_fields``hermes_tools_mindmap_apply_ops_rejects_stale_revision``hermes_tools_mindmap_apply_ops_shared_read_is_forbidden` 覆盖。resource tab / File Tree 可见性和 Page AI mindmap contextRefs 已由 `task455``task524``task525` 验收。后续若继续扩展 `moveNode``insertSiblingAfter``setHyperlink``setRefs``appendNote``patchView`,应另拆 P2 follow-up,不阻塞本轮最小闭环。
## 12. 第一批执行建议
第一批只做可控闭环:
1. 新增 `skills/mnote-mindmap/SKILL.md`
2.`hermes_tools::skill` 注册 `mnote-mindmap`
3. 补 Page AI skill 面板 smoke。
4.`mnote.skill.read` 单测。
5. 增强 `mnote.mindmap.fetch` 输出,识别当前默认 envelope。
6. 新增 `mnote.mindmap.create_from_outline` dry-run 与真实写入。
7. 用 fixture 模拟 PDF 摘要,不接真实 PDF OCR。
第二批再做:
1. 补浏览器 smoke,验证新建或修改后的 mindmap 能在 File Tree / Resource Tab 可见。
2. 接入真实 PDF / Office / MinerU 结果。
3. 在资源 tab 中把当前 mindmap 自动注入 Page AI contextRefs。
4. 按真实编辑需求继续扩展 `apply_ops`,例如 `moveNode``insertSiblingAfter``setHyperlink``setRefs``appendNote``patchView`