500 lines
19 KiB
Markdown
500 lines
19 KiB
Markdown
# 7-70 Page AI Pi Lab 原生 OpenHub-like UI 设计 v1
|
||||
|
|
|
|||
|
|
状态:done
|
|||
|
|
Owner:07-ai / mnote-web / page-ai-runtime
|
|||
|
|
日期:2026-07-04
|
|||
|
|
|
|||
|
|
## 1. 结论
|
|||
|
|
|
|||
|
|
Pi Lab 下一阶段不做第二个 iframe,也不把 `@earendil-works/pi-web-ui` 或 LibreChat / Open WebUI 这类完整应用直接嵌入 MNote。正确方向是:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
MNote Page AI 独立 Pi Lab 浮动入口 + 原生抽屉 UI
|
|||
|
|
-> 体验参考当前 OpenHub AI 面板,但入口和容器不依赖 OpenHub
|
|||
|
|
-> 运行协议参考 @assistant-ui/react-pi 的 PiClient / HTTP SSE thread contract
|
|||
|
|
-> 消息、composer、tool、artifact 形态参考 Pi 官方 web-ui 与 ai-elements
|
|||
|
|
-> 权限、知识库、receipt、watcher refresh 继续由 MNote 托管
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
OpenHub 继续作为默认 Page AI 主线。Pi Lab 使用独立浮动按钮与独立抽屉容器,默认在 MNote 页面中显示;目标是把 7-69 的 debug spike UI 升级成可验证的 MNote-native Page AI 体验,而不是替代或复用 OpenHub 的入口。若后续确认不需要 Pi Lab,直接退役这一独立入口和 runtime 即可,不需要先用 feature flag 隔离。
|
|||
|
|
|
|||
|
|
## 2. 原则
|
|||
|
|
|
|||
|
|
- **独立入口默认显示**:Pi Lab 新增自己的悬浮按钮和抽屉容器,默认显示,不复用当前 OpenHub 的按钮、iframe 页面或 provider tab 容器;以后退役 OpenHub 或 Pi Lab 任一侧,都不影响另一侧。
|
|||
|
|
- **原生承载**:Pi Lab UI 渲染在 MNote 自有 DOM 中,不新增独立产品页作为主验收面,不 iframe 第二个完整 AI 应用。
|
|||
|
|
- **优先参考和复用**:能复用当前 OpenHub 已证明的交互、Pi 官方 UI 的事件语义、assistant-ui 的 runtime contract、ai-elements 的组件形态,就不要自造一套孤立协议。
|
|||
|
|
- **MNote 拥有真相**:session binding、allowed roots、LightRAG facade、tool receipt、file patch、citation/open-reference、watcher refresh 仍归 MNote;第三方 UI 不能接管这些事实源。
|
|||
|
|
- **Debug 后置**:Page AI 首屏必须是对话、输入、上下文和变更结果;runtime health、scope JSON、receipt 原文只进折叠诊断区或开发态右栏。
|
|||
|
|
- **不破坏 OpenHub**:OpenHub 仍是默认入口和默认 Page AI 主线;Pi Lab 作为独立入口与 OpenHub 并列但互不依赖,不出现普通用户可见的 fallback/迁移暗示。
|
|||
|
|
|
|||
|
|
## 3. 参考资源取证
|
|||
|
|
|
|||
|
|
### 3.1 当前 OpenHub UI
|
|||
|
|
|
|||
|
|
本地 OpenHub 是当前最接近目标体验的产品基线:
|
|||
|
|
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/pages/SmartQueryPage.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/ChatInput.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/AssistantMessage.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/ToolCall.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/HistoryDrawer.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/DiffViewer.jsx`
|
|||
|
|
- `/mnt/Data1T/Mnote_data/openhub/OpenHub/smart-query-frontend/src/components/KnowledgeManager.jsx`
|
|||
|
|
|
|||
|
|
可参考能力:
|
|||
|
|
|
|||
|
|
- 顶部/底部紧凑控制区:agent mode、model select、当前页面/当前文件夹按钮。
|
|||
|
|
- 主消息流:user / assistant bubble、streaming、retry / undo、idle state。
|
|||
|
|
- assistant message:reasoning 折叠、tool summary、tool cards、citation chips。
|
|||
|
|
- session/history:历史抽屉、恢复会话、归档。
|
|||
|
|
- changed files / diff:隐藏索引桥接 MNote,用户侧展示 changed files / diff 入口。
|
|||
|
|
- knowledge:知识库入口和 citation 回跳模式。
|
|||
|
|
|
|||
|
|
不直接复用方式:
|
|||
|
|
|
|||
|
|
- 不把 OpenHub React/AntD 组件直接搬进 `mnote-web` 主运行时。
|
|||
|
|
- 不复制 OpenHub session/message 全文存储作为 Pi Lab 真相。
|
|||
|
|
- 不复用 OpenHub iframe shell 实现 Pi Lab,因为用户目标是 MNote-native。
|
|||
|
|
|
|||
|
|
### 3.2 Pi 官方 web-ui
|
|||
|
|
|
|||
|
|
`@earendil-works/pi-web-ui@0.75.3` 已核验为 MIT 包,描述为 “Reusable web UI components for AI chat interfaces powered by @earendil-works/pi-ai”。包内包含:
|
|||
|
|
|
|||
|
|
- `ChatPanel`
|
|||
|
|
- `AgentInterface`
|
|||
|
|
- `MessageList` / `Messages`
|
|||
|
|
- `MessageEditor`
|
|||
|
|
- `StreamingMessageContainer`
|
|||
|
|
- `ThinkingBlock`
|
|||
|
|
- tool renderers
|
|||
|
|
- artifacts runtime / sandbox
|
|||
|
|
- `ModelSelector`
|
|||
|
|
- IndexedDB storage stores
|
|||
|
|
|
|||
|
|
可参考能力:
|
|||
|
|
|
|||
|
|
- Pi 消息流与工具流的视觉分层。
|
|||
|
|
- thinking / tool / artifact 的独立组件边界。
|
|||
|
|
- composer 与 model/thinking selector 的组合方式。
|
|||
|
|
- artifacts-style 侧栏。
|
|||
|
|
|
|||
|
|
不直接整包接入原因:
|
|||
|
|
|
|||
|
|
- 默认假设 browser 侧持有 `Agent`、provider keys、IndexedDB session/settings。
|
|||
|
|
- 默认可暴露 Pi 自带 tools / attachments / artifacts 事实源。
|
|||
|
|
- 与 MNote 后端托管 Pi RPC/SSE、AiAccessScope、MNote-owned tools 的边界冲突。
|
|||
|
|
|
|||
|
|
迁移条件:
|
|||
|
|
|
|||
|
|
- 先提供 remote-session adapter,使 `ChatPanel` / `AgentInterface` 不直接管理 provider key、IndexedDB 和 `Agent.state.tools`。
|
|||
|
|
- 所有 tool call、file read/write、knowledge query、receipt 仍必须走 MNote facade。
|
|||
|
|
|
|||
|
|
### 3.3 assistant-ui / react-pi
|
|||
|
|
|
|||
|
|
`@assistant-ui/react-pi@0.0.5` 已核验为 MIT,说明其 browser entry 是 RPC-isomorphic `PiClient`,通过 HTTP/SSE 驱动 Pi-backed threads。其 contract 包含:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
GET /threads
|
|||
|
|
POST /threads
|
|||
|
|
GET /threads/:id
|
|||
|
|
PATCH /threads/:id
|
|||
|
|
POST /threads/:id/messages
|
|||
|
|
POST /threads/:id/cancel
|
|||
|
|
GET /models
|
|||
|
|
POST /threads/:id/model
|
|||
|
|
POST /threads/:id/thinking
|
|||
|
|
GET /threads/:id/events
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
可参考能力:
|
|||
|
|
|
|||
|
|
- thread / message / composer / queue / cancel 的协议边界。
|
|||
|
|
- snapshot-first SSE reconnect 语义。
|
|||
|
|
- model / thinking controls。
|
|||
|
|
- host UI approval requests。
|
|||
|
|
- tool-associated approval / interrupt 的 UI 映射。
|
|||
|
|
|
|||
|
|
当前不直接引 React UI 的原因:
|
|||
|
|
|
|||
|
|
- `mnote-web` 当前主路径是 Rust SSR + browser JS,不是 React app。
|
|||
|
|
- 直接引入 React island、Tailwind/shadcn 体系会扩大构建和运行时边界。
|
|||
|
|
- 当前优先目标是把 MNote-owned Pi adapter 做完整,而不是重开前端框架主线。
|
|||
|
|
|
|||
|
|
设计决策:**先对齐 contract,不先引 UI 框架**。后续如果 MNote 需要 React island,再以该 contract 为迁移桥。
|
|||
|
|
|
|||
|
|
### 3.4 ai-elements
|
|||
|
|
|
|||
|
|
`ai-elements@1.9.0` 已核验为 Apache-2.0,定位是基于 shadcn/ui 的 AI-native component registry。
|
|||
|
|
|
|||
|
|
可参考能力:
|
|||
|
|
|
|||
|
|
- message / conversation / prompt input / reasoning / tool / source / response card 的组件形态。
|
|||
|
|
- 更现代的 AI chat 视觉密度和状态表达。
|
|||
|
|
|
|||
|
|
当前不直接接入原因:
|
|||
|
|
|
|||
|
|
- 依赖 React、Tailwind、shadcn registry 和 CSS variables。
|
|||
|
|
- 对当前 MNote Rust SSR + browser JS 主路径引入成本偏高。
|
|||
|
|
|
|||
|
|
设计决策:作为视觉和组件拆分参考,不作为 7-70 第一阶段依赖。
|
|||
|
|
|
|||
|
|
### 3.5 完整应用类参考
|
|||
|
|
|
|||
|
|
LibreChat、Open WebUI、AnythingLLM、Continue、Cline、Roo Code 只作为交互模式参考:
|
|||
|
|
|
|||
|
|
- LibreChat / Open WebUI / AnythingLLM:参考历史会话、多模型、RAG、文件区、设置入口。
|
|||
|
|
- Continue / Cline / Roo Code:参考 agent tool timeline、审批、diff、changed files、任务状态。
|
|||
|
|
|
|||
|
|
不作为直接依赖或嵌入目标。
|
|||
|
|
|
|||
|
|
## 4. UI 目标结构
|
|||
|
|
|
|||
|
|
### 4.1 独立入口与抽屉整体
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
MNote page
|
|||
|
|
Pi Lab floating button(default visible)
|
|||
|
|
-> Pi Lab native drawer(independent from OpenHub iframe/page)
|
|||
|
|
topbar
|
|||
|
|
Pi Lab title
|
|||
|
|
session title
|
|||
|
|
runtime status
|
|||
|
|
close / minimize
|
|||
|
|
context strip
|
|||
|
|
current page chip
|
|||
|
|
selection chip
|
|||
|
|
allowed roots chip
|
|||
|
|
LightRAG chip
|
|||
|
|
model / thinking selector
|
|||
|
|
body
|
|||
|
|
message timeline
|
|||
|
|
optional right rail
|
|||
|
|
composer
|
|||
|
|
prompt input
|
|||
|
|
context buttons
|
|||
|
|
send / abort / queue state
|
|||
|
|
folded diagnostics
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
桌面端允许右侧 rail;移动端不显示右 rail,改为底部 sheet 或折叠 section。
|
|||
|
|
|
|||
|
|
入口规则:
|
|||
|
|
|
|||
|
|
- Pi Lab 使用独立悬浮按钮,例如右下角 `π`,默认渲染。
|
|||
|
|
- Pi Lab 点击后打开独立抽屉,不借用 OpenHub 当前按钮、OpenHub iframe 页或 OpenHub provider tab。
|
|||
|
|
- Pi Lab 抽屉可以视觉参考 OpenHub,但 DOM、状态、session、事件订阅、关闭/最小化都独立。
|
|||
|
|
- OpenHub 的现有按钮和页面保持不变;Pi Lab 不在 OpenHub 面板内新增 tab 作为主入口。
|
|||
|
|
- 若未来退役 OpenHub,Pi Lab 浮动入口仍可保留;若退役 Pi Lab,OpenHub 入口不受影响。
|
|||
|
|
- `MNOTE_PAGE_AI_PI_LAB` 可保留为临时开发/强制关闭开关,但不是产品入口显示的前置条件。
|
|||
|
|
|
|||
|
|
### 4.2 Topbar
|
|||
|
|
|
|||
|
|
目标是接近 OpenHub 的 AI 面板,而不是 debug 工具页。
|
|||
|
|
|
|||
|
|
必须包含:
|
|||
|
|
|
|||
|
|
- Pi Lab 标题与实验标记;不放 OpenHub/Pi provider tabs 作为主导航。
|
|||
|
|
- session label:`Pi Lab · 当前页面标题`,恢复会话后显示短 session id。
|
|||
|
|
- runtime status:idle / starting / streaming / error。
|
|||
|
|
- model label:默认 `omniroute/freefirst`,可后续扩展 selector。
|
|||
|
|
- close/minimize。
|
|||
|
|
|
|||
|
|
不要在 topbar 放大段 `scope`、`disabled builtins`、raw env 等诊断文案。
|
|||
|
|
|
|||
|
|
### 4.3 Context Strip
|
|||
|
|
|
|||
|
|
替代当前偏 debug 的工具列表,参考 OpenHub `ChatInput` 中当前页面/文件夹按钮:
|
|||
|
|
|
|||
|
|
- 当前页:真实 `.md` 路径或页面标题,点击在 MNote 中定位。
|
|||
|
|
- 选区:无选区时 disabled,有选区时显示字符数。
|
|||
|
|
- allowed roots:显示 root 名称和数量,点击展开只读详情。
|
|||
|
|
- LightRAG:显示 provider 状态;query citation 走 `mnote.reference.open`。
|
|||
|
|
- 文件变更:当前 session 有 patch 后显示 changed files chip。
|
|||
|
|
|
|||
|
|
Context strip 是用户可理解的任务上下文,不展示 JSON。
|
|||
|
|
|
|||
|
|
### 4.4 Message Timeline
|
|||
|
|
|
|||
|
|
消息模型要吸收 OpenHub `AssistantMessage` 与 Pi/assistant-ui 的 part 语义:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
MNotePiUiMessage
|
|||
|
|
id
|
|||
|
|
role = user | assistant | system
|
|||
|
|
status = queued | streaming | done | error | aborted
|
|||
|
|
createdAt
|
|||
|
|
model
|
|||
|
|
parts[]
|
|||
|
|
|
|||
|
|
MNotePiUiPart
|
|||
|
|
text
|
|||
|
|
reasoning
|
|||
|
|
toolCall
|
|||
|
|
toolResult
|
|||
|
|
citation
|
|||
|
|
diff
|
|||
|
|
fileChange
|
|||
|
|
approval
|
|||
|
|
error
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
展示规则:
|
|||
|
|
|
|||
|
|
- user message 右侧气泡。
|
|||
|
|
- assistant message 左侧主体块,正文优先。
|
|||
|
|
- reasoning 默认折叠,严禁把 provider `reasoning_content` 混入 final answer。
|
|||
|
|
- tool timeline 默认折叠成 summary,运行中自动展开当前 tool。
|
|||
|
|
- tool 输入/输出长 JSON 默认收起,显示摘要和 deny reason。
|
|||
|
|
- citation 显示为来源 chip,点击走 MNote open-reference。
|
|||
|
|
- diff / fileChange 显示为 changed file chips + diff summary,点击走 MNote document pane / diff view。
|
|||
|
|
- error 明确显示 provider/runtime/tool deny,不伪装成功。
|
|||
|
|
|
|||
|
|
### 4.5 Tool Timeline
|
|||
|
|
|
|||
|
|
参考 OpenHub `ToolCall.jsx`、Pi official tool renderers、Cline/Roo 的工具审批流。
|
|||
|
|
|
|||
|
|
第一阶段必须覆盖:
|
|||
|
|
|
|||
|
|
- `mnote.current_page.read`
|
|||
|
|
- `mnote.selection.read`
|
|||
|
|
- `mnote.allowed_roots.describe`
|
|||
|
|
- `mnote.local_file.read`
|
|||
|
|
- `mnote.local_file.patch`
|
|||
|
|
- `mnote.knowledge_rag.query`
|
|||
|
|
- `mnote.reference.open`
|
|||
|
|
- `mnote.tool_receipt.write`
|
|||
|
|
|
|||
|
|
每个 tool card 至少显示:
|
|||
|
|
|
|||
|
|
- tool name
|
|||
|
|
- state:pending / running / allowed / denied / error / done
|
|||
|
|
- compact params summary
|
|||
|
|
- deny reason
|
|||
|
|
- receipt id
|
|||
|
|
- file version before / after
|
|||
|
|
- diff summary
|
|||
|
|
- citation count
|
|||
|
|
|
|||
|
|
默认禁用 Pi 原始 `bash/read/write/edit` 的状态可以放在折叠详情里,不占据首屏。
|
|||
|
|
|
|||
|
|
### 4.6 Composer
|
|||
|
|
|
|||
|
|
参考 OpenHub `ChatInput`、Pi `MessageEditor`、assistant-ui composer queue 语义。
|
|||
|
|
|
|||
|
|
第一阶段:
|
|||
|
|
|
|||
|
|
- 多行输入。
|
|||
|
|
- icon-only 当前页、选区、文件夹/allowed roots、LightRAG 按钮,带 tooltip 和 aria-label。
|
|||
|
|
- send 按钮。
|
|||
|
|
- streaming 时显示 abort;若后端支持 queue,再允许 follow-up queue。
|
|||
|
|
- 发送前自动附带 MNote context envelope,不把上下文 URL 或 JSON 写入 textarea。
|
|||
|
|
- 禁用态要有明确原因:未启动 runtime、missing model、missing auth、scope denied。
|
|||
|
|
|
|||
|
|
后续阶段:
|
|||
|
|
|
|||
|
|
- model selector。
|
|||
|
|
- thinking level selector。
|
|||
|
|
- thread queue / steer。
|
|||
|
|
- prompt template / skill picker。
|
|||
|
|
|
|||
|
|
### 4.7 Right Rail / Drawer
|
|||
|
|
|
|||
|
|
桌面端右侧 rail 承接“有用但不该挤占主对话”的信息:
|
|||
|
|
|
|||
|
|
- session/history:当前只显示当前 session 与最近 session,完整历史后续做抽屉。
|
|||
|
|
- changed files:变更文件列表、patch count、打开按钮。
|
|||
|
|
- citations:本轮 citation 列表。
|
|||
|
|
- receipts:最近 tool receipts,默认摘要。
|
|||
|
|
- runtime:Pi PID / provider session id / runtime mode,只在 dev mode 显示。
|
|||
|
|
|
|||
|
|
移动端右 rail 不常驻,改为按钮展开底部 sheet。
|
|||
|
|
|
|||
|
|
### 4.8 Diagnostics
|
|||
|
|
|
|||
|
|
折叠 diagnostics 只面向开发:
|
|||
|
|
|
|||
|
|
- raw SSE events tail。
|
|||
|
|
- allowed roots raw snapshot。
|
|||
|
|
- receipt raw JSON。
|
|||
|
|
- runtime command / pid / session dir。
|
|||
|
|
- disabled builtin tools。
|
|||
|
|
|
|||
|
|
默认折叠,不参与普通用户验收截图。
|
|||
|
|
|
|||
|
|
## 5. 后端与协议设计
|
|||
|
|
|
|||
|
|
### 5.1 保留现有 7-69 endpoint
|
|||
|
|
|
|||
|
|
当前 7-69 已有:
|
|||
|
|
|
|||
|
|
- `/api/page-ai/pi/status`
|
|||
|
|
- `/api/page-ai/pi/bootstrap`
|
|||
|
|
- `/api/page-ai/pi/start`
|
|||
|
|
- `/api/page-ai/pi/send`
|
|||
|
|
- `/api/page-ai/pi/abort`
|
|||
|
|
- `/api/page-ai/pi/events`
|
|||
|
|
- `/api/page-ai/pi/tool-call`
|
|||
|
|
- `/page-ai/pi`
|
|||
|
|
|
|||
|
|
7-70 不要求立即破坏这些 endpoint。
|
|||
|
|
|
|||
|
|
但前端入口要调整为默认显示的独立浮动按钮与独立 drawer host;`/page-ai/pi` 可保留为 debug/internal 直达页,不作为产品主验收入口。
|
|||
|
|
|
|||
|
|
### 5.2 新增 PiClient-aligned adapter 层
|
|||
|
|
|
|||
|
|
为了后续能接 `@assistant-ui/react-pi` 或复用其 reducer 语义,新增 provider-neutral adapter contract:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
GET /api/page-ai/pi/threads
|
|||
|
|
POST /api/page-ai/pi/threads
|
|||
|
|
GET /api/page-ai/pi/threads/:id
|
|||
|
|
POST /api/page-ai/pi/threads/:id/messages
|
|||
|
|
POST /api/page-ai/pi/threads/:id/cancel
|
|||
|
|
GET /api/page-ai/pi/threads/:id/events
|
|||
|
|
GET /api/page-ai/pi/models
|
|||
|
|
POST /api/page-ai/pi/threads/:id/model
|
|||
|
|
POST /api/page-ai/pi/threads/:id/thinking
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
兼容策略:
|
|||
|
|
|
|||
|
|
- 第一阶段可在前端 adapter 中把旧 endpoint 映射为 thread contract。
|
|||
|
|
- 后端可逐步增加新 endpoint;旧 smoke 不被破坏。
|
|||
|
|
- SSE 必须 snapshot-first:重连先发当前 thread snapshot,再发 live events。
|
|||
|
|
- browser disconnect 不等于 abort;只有 cancel/abort 明确停止 runtime。
|
|||
|
|
|
|||
|
|
### 5.3 UI event normalization
|
|||
|
|
|
|||
|
|
Pi RPC / mock / future SDK event 统一归一为:
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
thread_snapshot
|
|||
|
|
message_created
|
|||
|
|
message_delta
|
|||
|
|
message_completed
|
|||
|
|
reasoning_delta
|
|||
|
|
tool_call_started
|
|||
|
|
tool_call_updated
|
|||
|
|
tool_call_completed
|
|||
|
|
tool_call_denied
|
|||
|
|
citation_added
|
|||
|
|
file_patch_applied
|
|||
|
|
receipt_written
|
|||
|
|
runtime_status_changed
|
|||
|
|
thread_error
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
所有 UI 只消费 normalized events,不直接依赖 Pi JSONL 原始字段。
|
|||
|
|
|
|||
|
|
## 6. 数据与权限边界
|
|||
|
|
|
|||
|
|
- `AiAccessScope` / allowed roots 是所有 file tool 的唯一授权来源。
|
|||
|
|
- Pi Lab UI 只显示 allowed roots 摘要,不允许用户从 UI 临时扩大 root。
|
|||
|
|
- `mnote.local_file.read` / `patch` 必须返回 normalized path、root id、deny reason、file version。
|
|||
|
|
- LightRAG 继续是唯一默认 knowledge provider;Pi 只能通过 `mnote.knowledge_rag.query` 查询。
|
|||
|
|
- citation 点击必须走 `mnote.reference.open` / MNote open-reference,不直接让 Pi 打开文件。
|
|||
|
|
- receipt 当前仍可落 provider-neutral adapter,但 UI v2 必须按 Turso/libSQL 迁移目标设计字段。
|
|||
|
|
- 文件 patch 后必须通过 MNote watcher / document refresh 链路更新 tiptap;禁止新增轮询刷新。
|
|||
|
|
|
|||
|
|
## 7. 实施阶段
|
|||
|
|
|
|||
|
|
### Phase A:Native UI v2 骨架
|
|||
|
|
|
|||
|
|
修改范围:
|
|||
|
|
|
|||
|
|
- `rust/crates/mnote-web/browser/sidebar-page-ai-pi-lab-runtime.js`
|
|||
|
|
- `scripts/task-pi-lab-static-smoke.js`
|
|||
|
|
- `scripts/task-pi-lab-browser-smoke.js`
|
|||
|
|
- 必要时补 `rust/crates/mnote-web/src/ssr/styles/components/page-ai.css`
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
- 当前 Pi Lab 从 debug shell 升级为 OpenHub-like 抽屉。
|
|||
|
|
- Pi Lab 使用独立悬浮按钮打开独立抽屉,不复用 OpenHub 按钮、OpenHub iframe 页面或 provider tab。
|
|||
|
|
- 首屏只保留对话、context strip、composer。
|
|||
|
|
- tool receipts / diagnostics 默认后置。
|
|||
|
|
- 截图必须显示:在 MNote 当前页面中通过独立 `π` 浮动按钮打开 Pi Lab 原生抽屉,非 OpenHub iframe、非独立页、非 OpenHub provider tab。
|
|||
|
|
|
|||
|
|
### Phase B:Event / message model 收口
|
|||
|
|
|
|||
|
|
修改范围:
|
|||
|
|
|
|||
|
|
- `sidebar-page-ai-pi-lab-runtime.js`
|
|||
|
|
- `rust/crates/mnote-web/src/routes/page_ai_pi.rs`
|
|||
|
|
- smoke 脚本
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
- 新增 normalized event reducer。
|
|||
|
|
- reasoning、tool、citation、diff、receipt 不再混杂在一条 debug 文本里。
|
|||
|
|
- SSE reconnect snapshot-first。
|
|||
|
|
- abort/cancel 明确区分 browser disconnect。
|
|||
|
|
|
|||
|
|
### Phase C:PiClient-aligned adapter
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
- 增加或前端模拟 `/threads` contract。
|
|||
|
|
- `send` / `cancel` / `events` 对齐 `@assistant-ui/react-pi` 的语义。
|
|||
|
|
- 保持旧 endpoint 兼容,直到 smoke 全部迁移。
|
|||
|
|
|
|||
|
|
### Phase D:OpenHub-like 功能补齐
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
- session history 抽屉。
|
|||
|
|
- changed files rail。
|
|||
|
|
- citation list。
|
|||
|
|
- diff preview。
|
|||
|
|
- model / thinking selector。
|
|||
|
|
- tool approval / host UI requests。
|
|||
|
|
|
|||
|
|
### Phase E:第三方组件复用决策
|
|||
|
|
|
|||
|
|
进入条件:
|
|||
|
|
|
|||
|
|
- Phase A-D 浏览器截图和 smoke 通过。
|
|||
|
|
- 当前 MNote native UI 已形成稳定 message/event model。
|
|||
|
|
|
|||
|
|
决策:
|
|||
|
|
|
|||
|
|
- 若 MNote 仍保持非 React 主路径:继续原生实现,只参考 Pi web-ui / ai-elements。
|
|||
|
|
- 若引入 React island:优先评估 `assistant-ui + @assistant-ui/react-pi`,并复用 Phase C contract。
|
|||
|
|
- 若官方 Pi web-ui 提供 remote-session adapter:评估局部复用 `AgentInterface` / `Messages` / `MessageEditor`,不得引入 browser provider key 和 IndexedDB 作为 MNote 真相。
|
|||
|
|
|
|||
|
|
## 8. 验收标准
|
|||
|
|
|
|||
|
|
- OpenHub 默认入口不变。
|
|||
|
|
- MNote 默认显示独立 Pi Lab 浮动按钮;点击后打开独立 Pi Lab 原生抽屉。
|
|||
|
|
- Pi Lab 不复用 OpenHub 按钮、OpenHub 页面或 OpenHub iframe 容器。
|
|||
|
|
- UI 首屏接近 OpenHub:消息流、上下文、输入框、模型/状态、tool/citation/diff 摘要齐全。
|
|||
|
|
- 不出现第二个 iframe AI 应用。
|
|||
|
|
- 可发送 prompt、接收 stream、abort。
|
|||
|
|
- reasoning 折叠且不泄漏到 final answer。
|
|||
|
|
- tool call 显示状态、deny reason、receipt id。
|
|||
|
|
- allowed roots 越界读写在 UI 中显示 denied。
|
|||
|
|
- LightRAG citation 可点击回跳。
|
|||
|
|
- 当前 `.md` patch 后显示 changed file,并通过 watcher refresh 当前 tiptap 页。
|
|||
|
|
- diagnostics 默认折叠。
|
|||
|
|
- browser smoke 输出截图。
|
|||
|
|
|
|||
|
|
## 9. 明确非目标
|
|||
|
|
|
|||
|
|
- 不替换 OpenHub。
|
|||
|
|
- 不把 Pi Lab 做成普通用户默认入口。
|
|||
|
|
- 不 iframe LibreChat / Open WebUI / AnythingLLM / Pi web-ui demo app。
|
|||
|
|
- 不把 Pi Lab 做成 OpenHub 面板内部的 provider tab 或复用 OpenHub 页面容器。
|
|||
|
|
- 不把 React / shadcn / Tailwind 作为 7-70 Phase A 必需依赖。
|
|||
|
|
- 不开放 Pi 原始 bash、无约束 read/write/edit。
|
|||
|
|
- 不新增第二套 RAG。
|
|||
|
|
- 不把 OpenHub 或 Pi 的 session JSONL 作为 MNote control-plane 长期真相。
|
|||
|
|
|
|||
|
|
## 10. 当前后续任务
|
|||
|
|
|
|||
|
|
- [ ] Phase A:重做 `sidebar-page-ai-pi-lab-runtime.js` 信息架构、独立浮动入口与视觉层级。
|
|||
|
|
- [ ] Phase A:更新 browser smoke,截图验证独立 `π` 浮动按钮打开 OpenHub-like Pi Lab 抽屉。
|
|||
|
|
- [ ] Phase B:抽出 normalized event reducer。
|
|||
|
|
- [ ] Phase C:补 PiClient-aligned thread adapter。
|
|||
|
|
- [ ] Phase D:补 changed files / diff / citation rail。
|
|||
|
|
- [ ] Phase E:重新评估是否引入 `assistant-ui` 或 Pi official remote-session adapter。
|