404 lines
14 KiB
Markdown
404 lines
14 KiB
Markdown
# 7-63 [recycle] Page AI Board-first product shell v1
|
||
|
||
> 创建时间:2026-06-20
|
||
>
|
||
> 当前状态:`RECYCLE`
|
||
>
|
||
> Owner:07-ai / Page AI product shell / Agent Board MNote runtime / session history
|
||
>
|
||
> 上位依据:
|
||
> - `design/07-ai/done/7-62-page-ai-board-first-full-rewrite-v1.md`
|
||
> - `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md`
|
||
> - `design/07-ai/done/7-38-page-ai-sidebar-runtime-owner-split-v1.md`
|
||
> - `design/07-ai/done/7-40-page-ai-context-envelope-and-run-receipt-v1.md`
|
||
> - `design/07-ai/done/7-60-page-ai-settings-ia-cleanup-v1.md`
|
||
|
||
> 过时原因:已由 `design/07-ai/process/7-65-opencode-webui-embed-page-ai-v1.md` 替代;Page AI 新主路径只接入 opencode 官方 runtime + 官方 WebUI。
|
||
|
||
## 1. 当前结论
|
||
|
||
7-62 已经证明 Board-first 主链能跑:MNote Page AI 可以通过 Agent Board 创建 run,可以把 MNote capability/envelope 下发给 worker,`mnote-page-ai-zcode` 能回复,也能真实编辑当前 Markdown 文件并触发编辑器刷新。
|
||
|
||
但这还不是合格的页面 AI。当前问题不是“再给用户更多 Board 选择”,而是 **MNote 页面 AI 需要自己的产品壳**:
|
||
|
||
```text
|
||
MNote Page AI Product Shell
|
||
= 聊天体验 + 当前页上下文 + MNote 白名单 worker/workflow + worker 内模型选择 + session/history + run detail
|
||
|
||
Agent Board MNote Runtime
|
||
= MNote 专用 worker + MNote 专用 workflow + provider/model 执行 + receipt/event 持久化
|
||
```
|
||
|
||
Page AI 不是 Agent Board 控制台的缩小版。默认 UI 不应该暴露 Board 全量 worker、全量 workflow、provider adapter 或通用任务报告。用户只需要面对少量 MNote 语义清楚的选择。
|
||
|
||
## 2. 要解决的四个问题
|
||
|
||
### 2.1 Worker 怎么选
|
||
|
||
Page AI 只能选择 MNote Page AI 白名单 worker。当前默认只有:
|
||
|
||
```text
|
||
workerPresetId = mnote-page-ai-zcode
|
||
name = MNote 页面 AI · ZCode
|
||
surface = mnote-page-ai
|
||
capabilities = text, repo-edit, terminal, mnote-capability-envelope, local-markdown-edit
|
||
```
|
||
|
||
不暴露 Board 全量 worker catalog。Reasonix、Codex、ZCode、QA worker 都是 Board 内部 worker 类型,不直接成为 MNote 页面用户的选择项。后续如果需要新增 worker,必须在代码中显式登记为 `surface=mnote-page-ai`,同时补齐:
|
||
|
||
- 用户可见名称。
|
||
- 适合场景。
|
||
- 允许模型档位。
|
||
- 权限能力。
|
||
- smoke 验收。
|
||
|
||
当白名单只有一个 worker 时,UI 不显示“可切换 worker”的伪入口,只显示当前 worker 和模型档位。
|
||
|
||
### 2.2 模型怎么改
|
||
|
||
模型选择挂在特定 MNote worker 下,不做 provider picker:
|
||
|
||
```text
|
||
workerPresetId = mnote-page-ai-zcode
|
||
modelOverride = zcode-default | zcode-fast | zcode-strong
|
||
```
|
||
|
||
UI 展示为 worker chip 旁的 model chip,例如:
|
||
|
||
```text
|
||
MNote 页面 AI · ZCode / 默认
|
||
```
|
||
|
||
用户可以切换模型档位,但不能直接选择 provider。MNote 不重新维护 Hermes/Reasonix/Codex/ZCode provider adapter;provider 和 credential 仍归 Board。
|
||
|
||
### 2.3 Workflow 怎么选
|
||
|
||
Page AI 只能选择 MNote Page AI 白名单 workflow。当前默认只有:
|
||
|
||
```text
|
||
workflowId = builtin-mnote-page-ai-chat
|
||
name = MNote 页面 AI
|
||
surface = mnote-page-ai
|
||
```
|
||
|
||
该 workflow 覆盖默认聊天、当前页轻编辑、当前页总结、当前页问答。通用 Board workflow 不出现在 Page AI picker 中。
|
||
|
||
后续确实需要时,再通过代码加入特定 MNote workflow:
|
||
|
||
| Workflow | 加入条件 | 默认 UI |
|
||
| --- | --- | --- |
|
||
| `builtin-mnote-page-ai-chat` | 已有默认主链 | 默认启用 |
|
||
| `builtin-mnote-page-ai-edit` | 需要更明确的编辑阶段和 diff/receipt | 加入白名单后显示 |
|
||
| `builtin-mnote-page-ai-review` | 需要当前页审阅、总结、检查 | 加入白名单后显示 |
|
||
|
||
复杂开发、hotfix、QA/browser workflow 不作为默认页面 AI 能力。只有当它们被改造成 MNote 专用 workflow,并明确加入白名单后,才允许显示。
|
||
|
||
### 2.4 Session 怎么选、怎么看历史
|
||
|
||
Page AI session 迁移为 Board-first session。每条 assistant 消息必须知道它来自哪个 Board run,但主聊天只显示用户需要的回答。
|
||
|
||
```json
|
||
{
|
||
"schema": "mnote.page_ai.session.v2",
|
||
"sessionId": "...",
|
||
"workspaceId": "...",
|
||
"documentId": "...",
|
||
"rootUri": "file:///...",
|
||
"messages": [
|
||
{ "role": "user", "content": "hi,收到请回复收到。" },
|
||
{
|
||
"role": "assistant",
|
||
"content": "收到。",
|
||
"boardRunId": "...",
|
||
"workflowId": "builtin-mnote-page-ai-chat",
|
||
"workerPresetId": "mnote-page-ai-zcode",
|
||
"modelOverride": "zcode-default",
|
||
"receiptId": "..."
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
历史 UI 分三层:
|
||
|
||
1. 会话列表:标题、最后回答摘要、状态、时间。
|
||
2. 会话详情:聊天消息、当前页上下文、关联 run。
|
||
3. Run detail:worker、model、workflow、timeline、changed files、receipt、失败原因。
|
||
|
||
短期可继续 localStorage/sessionStorage;产品化阶段必须落到 SQLite control-plane,避免刷新、跨标签和权限变化导致历史丢失。
|
||
|
||
## 3. 源头输出合同
|
||
|
||
MNote 专用 worker/workflow 必须从源头产出页面 AI 风格回答,而不是先产出 Board 任务报告再让 MNote 截断。
|
||
|
||
### 3.1 用户回答
|
||
|
||
简单 ask 的 worker 最终回答应直接是:
|
||
|
||
```markdown
|
||
收到。
|
||
```
|
||
|
||
当前页编辑任务的最终回答应类似:
|
||
|
||
```markdown
|
||
已把当前页面中的“A”替换为“B”。
|
||
```
|
||
|
||
不允许把以下内容作为主回答:
|
||
|
||
- `Completed`
|
||
- `Comments`
|
||
- `Remaining`
|
||
- `Agent Board run 已创建`
|
||
- 命令日志
|
||
- 工具调用过程
|
||
- provider 内部推理或计划
|
||
|
||
### 3.2 运行记录
|
||
|
||
Board runtime/workflow 负责旁路写入结构化记录:
|
||
|
||
```json
|
||
{
|
||
"schema": "agent_board.workflow_run_receipt.v2",
|
||
"runId": "...",
|
||
"surface": "mnote-page-ai",
|
||
"workflowId": "builtin-mnote-page-ai-chat",
|
||
"workerPresetId": "mnote-page-ai-zcode",
|
||
"modelOverride": "zcode-default",
|
||
"finalAnswer": "收到。",
|
||
"changedFiles": [],
|
||
"verification": [],
|
||
"remaining": [],
|
||
"eventsUrl": "/api/workflow-runs/:id/events",
|
||
"createdAt": 0,
|
||
"completedAt": 0
|
||
}
|
||
```
|
||
|
||
`## FINAL_ANSWER` 只作为旧 run 或非专用 workflow 的兼容保护,不是长期主路径。长期主路径是 worker 主回答自然、Board receipt 结构化。
|
||
|
||
## 4. Board 和 MNote 的双向接口
|
||
|
||
### 4.1 Board route result
|
||
|
||
Board 提供 MNote surface 的推荐结果:
|
||
|
||
```json
|
||
{
|
||
"schema": "agent_board.page_ai_route.v2",
|
||
"surface": "mnote-page-ai",
|
||
"workflowId": "builtin-mnote-page-ai-chat",
|
||
"workflowName": "MNote 页面 AI",
|
||
"workerPresetId": "mnote-page-ai-zcode",
|
||
"workerName": "MNote 页面 AI · ZCode",
|
||
"modelOverride": "zcode-default",
|
||
"allowedWorkerPresetIds": ["mnote-page-ai-zcode"],
|
||
"allowedWorkflowIds": ["builtin-mnote-page-ai-chat"],
|
||
"modelOptions": [
|
||
{ "id": "zcode-default", "label": "默认", "default": true },
|
||
{ "id": "zcode-fast", "label": "快速" },
|
||
{ "id": "zcode-strong", "label": "强力" }
|
||
],
|
||
"requiresConfirmation": false,
|
||
"requires": {
|
||
"filesystem": true,
|
||
"write": false,
|
||
"browser": false,
|
||
"vision": false
|
||
},
|
||
"stages": ["answer"]
|
||
}
|
||
```
|
||
|
||
MNote 消费 Board 推荐,但仍按本地白名单过滤。这样 Board 可以逐步提供更多能力,MNote 不会把控制台复杂度泄露给页面用户。
|
||
|
||
### 4.2 MNote run request
|
||
|
||
MNote 创建 run 时必须显式传入:
|
||
|
||
```json
|
||
{
|
||
"surface": "mnote-page-ai",
|
||
"workflowId": "builtin-mnote-page-ai-chat",
|
||
"workerPresetId": "mnote-page-ai-zcode",
|
||
"modelOverride": "zcode-default",
|
||
"capabilityEnvelope": {
|
||
"primaryTarget": { "absolutePath": "/.../current.md" },
|
||
"allowedRoots": ["/..."]
|
||
},
|
||
"sessionId": "..."
|
||
}
|
||
```
|
||
|
||
Board 必须拒绝不匹配 `surface=mnote-page-ai` 的 worker/workflow 组合,避免前端绕过白名单。
|
||
|
||
## 5. 标准页面 AI 最小体验
|
||
|
||
按 VSCode/Cursor 类页面 AI 衡量,第一阶段只补核心能力,不把 QA/browser/artifact 做成默认入口。
|
||
|
||
### 5.1 Chat
|
||
|
||
- [ ] 主聊天只显示用户消息和 assistant 自然回答。
|
||
- [ ] pending skeleton 或流式 token。
|
||
- [ ] stop 当前 run。
|
||
- [x] retry 同一消息。
|
||
- [ ] copy 回答。
|
||
- [ ] Enter 发送,Shift+Enter 换行。
|
||
|
||
### 5.2 Context
|
||
|
||
- [ ] composer 上方显示上下文 pills:当前页、选区、打开资源、文件夹、知识库。
|
||
- [ ] 当前 write target 单独显示。
|
||
- [ ] 无写权限时,编辑类 prompt 发送前提示授权缺失。
|
||
- [ ] `allowedRoots` 与 `primaryTarget` run 前可预检。
|
||
|
||
### 5.3 Worker / Model / Workflow
|
||
|
||
- [ ] 只展示 MNote Page AI 白名单 worker。
|
||
- [ ] 当只有一个 worker 时,不显示伪切换入口。
|
||
- [ ] 模型选择挂在当前 worker 下。
|
||
- [ ] 只展示 MNote Page AI 白名单 workflow。
|
||
- [ ] 切换 worker/model/workflow 后写入偏好和 session metadata。
|
||
|
||
### 5.4 Timeline / Diff / Receipt
|
||
|
||
- [ ] run detail 展示 Board event timeline。
|
||
- [ ] changed files 从 receipt 读取。
|
||
- [ ] Markdown 编辑后展示最小 diff 摘要。
|
||
- [ ] 命令输出默认折叠,失败时展开。
|
||
- [x] dirty/stale guard:编辑器未保存或文件外部变化时阻止自动写入。
|
||
|
||
### 5.5 Session / History
|
||
|
||
- [ ] 会话列表可见、可搜索、可恢复。
|
||
- [ ] 每条 assistant 消息关联 run id、worker、model、workflow、receipt。
|
||
- [ ] 历史详情可查看 final answer、timeline、changed files。
|
||
- [ ] 支持删除本地 history,不删除 Board 原始 run。
|
||
|
||
## 6. 非默认扩展
|
||
|
||
QA、浏览器截图和 artifact 展示不属于页面 AI 第一阶段核心体验。它们只在用户显式选择已加入白名单的 QA/browser workflow,或 Board route 判断确实需要浏览器验证并得到 UI 提示时出现。
|
||
|
||
- 默认 Page AI 不显示 QA/browser 入口。
|
||
- artifact screenshot 只从 run detail 打开,不进入主聊天。
|
||
- QA run 失败时主聊天只显示一句可理解失败原因,详情里展示日志。
|
||
|
||
## 7. 实施计划
|
||
|
||
### Phase A:源头回答收敛
|
||
|
||
- [x] Board 默认 worker 已改为 `mnote-page-ai-zcode`。
|
||
- [x] Board 默认 workflow 已改为 `builtin-mnote-page-ai-chat`。
|
||
- [x] MNote UI 已能只展示 final answer,不展示 Board run 创建日志。
|
||
- [x] smoke:`hi,收到请回复收到。` 最终 assistant 气泡只显示 `收到。`。
|
||
- [x] `mnote-page-ai-zcode` / `builtin-mnote-page-ai-chat` 源头默认输出自然语言 final answer。
|
||
- [x] 结构化记录写入 `receipt.finalAnswer / changedFiles / verification / remaining`。
|
||
|
||
### Phase B:白名单选择壳
|
||
|
||
- [x] MNote 定义 Page AI worker 白名单。
|
||
- [x] MNote 定义 Page AI workflow 白名单。
|
||
- [x] Worker picker 只展示白名单 worker。
|
||
- [x] Workflow picker 只展示白名单 workflow。
|
||
- [x] 当白名单只有一个 worker/workflow 时,不显示伪切换。
|
||
|
||
### Phase C:worker 内模型选择
|
||
|
||
- [x] Board route 返回 `modelOptions`。
|
||
- [x] MNote 显示当前 model chip。
|
||
- [x] Model picker 只展示当前 worker 允许的模型档位。
|
||
- [x] run payload 包含 `modelOverride`。
|
||
- [x] session metadata 记录 `modelOverride`。
|
||
|
||
### Phase D:Board-first session/history
|
||
|
||
- [x] 定义并落地 `mnote.page_ai.session.v2`。
|
||
- [x] assistant message 记录 `boardRunId/workflowId/workerPresetId/modelOverride/receiptId`。
|
||
- [x] 历史列表展示 Board-first session。
|
||
- [x] Run detail 可从历史打开。
|
||
- [x] 刷新页面后仍能恢复会话和 run 详情。
|
||
|
||
### Phase E:timeline / changed files / diff
|
||
|
||
- [x] 从 Board events 生成 timeline。
|
||
- [x] 从 receipt 提取 changed files。
|
||
- [x] Markdown 文件编辑后展示最小 diff / changed files 摘要。
|
||
- [x] 命令输出和日志折叠。
|
||
- [x] smoke:编辑当前页面后,主聊天是自然回复,详情里能看到 changed file 和验证命令。
|
||
|
||
### Phase F:标准页面 AI 体验补齐
|
||
|
||
- [ ] 上下文 pills 完整可交互。
|
||
- [x] pending skeleton / streaming 状态。
|
||
- [x] stop / retry / copy。
|
||
- [x] dirty/stale guard。
|
||
|
||
## 8. 验收标准
|
||
|
||
### 8.1 简单问答
|
||
|
||
- 输入:`hi,收到请回复收到。`
|
||
- 主聊天最新 assistant 气泡:`收到。`
|
||
- worker 源头最终回答就是自然语言,不依赖 MNote 截断通用任务报告。
|
||
- run detail 可查看 worker、model、workflow、run id、receipt。
|
||
|
||
### 8.2 Worker 与模型
|
||
|
||
- UI 只展示 MNote Page AI 白名单 worker。
|
||
- 白名单只有一个 worker 时,不显示 worker 切换列表。
|
||
- UI 能切换当前 worker 允许的模型档位。
|
||
- 发送后 payload 包含 `workerPresetId` 和 `modelOverride`。
|
||
- 不在白名单内的 worker 不显示。
|
||
|
||
### 8.3 Workflow
|
||
|
||
- UI 只展示 MNote Page AI 白名单 workflow。
|
||
- 默认 workflow 为 `builtin-mnote-page-ai-chat`。
|
||
- 不在白名单内的 Board workflow 不显示。
|
||
- 发送后 payload 包含 `workflowId`。
|
||
|
||
### 8.4 Session/history
|
||
|
||
- 新建会话、恢复会话、搜索历史可用。
|
||
- 历史项显示 final answer preview、状态、时间。
|
||
- 点击历史项恢复聊天消息。
|
||
- 点击 run detail 可查看 Board receipt。
|
||
|
||
### 8.5 页面编辑
|
||
|
||
- 输入“把当前页面中的 A 替换为 B”。
|
||
- worker 只修改 `primaryTarget.absolutePath`。
|
||
- 磁盘文件变化。
|
||
- 编辑器 watcher 刷新可见。
|
||
- 主聊天显示自然结果。
|
||
- 详情显示 changed files / verification。
|
||
|
||
## 9. 非目标
|
||
|
||
- 不重新实现 provider adapter;provider/model 执行仍归 Board。
|
||
- 不暴露 Board 全量 worker/workflow catalog。
|
||
- 不把复杂开发、hotfix、QA/browser workflow 默认化。
|
||
- 不删除 Hermes/Reasonix legacy 代码,只隐藏默认入口并防止污染默认主链。
|
||
- 不实现完整撤销系统,只保留 diff/receipt 所需数据结构。
|
||
|
||
## 10. 风险与处理
|
||
|
||
| 风险 | 处理 |
|
||
| --- | --- |
|
||
| MNote 专用 worker 仍输出任务报告 | 从 worker/workflow prompt 和 receipt API 源头修正,MNote 截取只做兼容保护 |
|
||
| Board 选择太多 | MNote 只展示白名单 worker/workflow,新增项必须代码登记 |
|
||
| 模型选择重新变成 provider picker | 模型挂在特定 worker 下,只展示该 worker 允许的档位 |
|
||
| Workflow 太重影响简单问答 | 默认只启用 `builtin-mnote-page-ai-chat`,复杂 workflow 需 MNote 白名单 |
|
||
| 历史数据分裂 | 新 session v2 记录 Board run,旧 session 只读兼容 |
|
||
| 文件编辑误伤 | primaryTarget + allowedRoots + dirty/stale guard + receipt |
|
||
|
||
## 11. 最小落地顺序
|
||
|
||
1. 先把 MNote 专用 worker/workflow 的源头输出改成自然回答。
|
||
2. 再把 Page AI UI 收敛为白名单 worker/workflow,不显示 Board 全量选择。
|
||
3. 然后补 worker 内模型选择。
|
||
4. 再补 Board-first session/history。
|
||
5. 最后补 timeline、diff、dirty/stale guard 和可选扩展。
|