142 lines
6.7 KiB
Markdown
142 lines
6.7 KiB
Markdown
# 7-71 统一 AI 管理面板与 Pi Lab 功能接入 — 实施检查清单
|
||||
|
|
|
|||
|
|
状态:partial — P0/P1/P2 完成;P3/P4/P5 管理员侧 OpenHub-like AI 管理与逐用户配置完成,用户自助偏好与 LightRAG 写管理待后续
|
|||
|
|
日期:2026-07-04
|
|||
|
|
|
|||
|
|
> 本清单与 `design/07-ai/process/7-71-unified-ai-management-control-plane-and-pi-lab-integration-v1.md` 的 §11 进度表保持同步。
|
|||
|
|
> process 文档保留架构结论;本文件记录已完成的检查项供快速验证。
|
|||
|
|
|
|||
|
|
## 已通过验收项
|
|||
|
|
|
|||
|
|
### P0 — 合同与只读聚合 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| `/api/ai-settings/effective` GET 端点已注册 | ✅ |
|
|||
|
|
| `/api/ai-settings/access-scopes` GET 端点已注册 | ✅ |
|
|||
|
|
| `/api/ai-admin/access-scopes` GET 端点已注册 | ✅ |
|
|||
|
|
| 所有 AI settings/scopes 端点无 POST/PUT/DELETE | ✅ |
|
|||
|
|
| `effective_settings` 使用 `load_active_directory_grants` 生成 allowed roots | ✅ |
|
|||
|
|
| `load_model_policy_and_quota` 不读取 `allowed_roots_json` | ✅ |
|
|||
|
|
| `source_of_truth` 声明为 `"directory_grants"` | ✅ |
|
|||
|
|
| 静态 smoke 27/27 通过 | ✅ |
|
|||
|
|
|
|||
|
|
### P1 — Pi Lab history 入库 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| `persist_upsert_run` 写入 `ai_runtime_runs` | ✅ |
|
|||
|
|
| `persist_append_event` 写入 `ai_runtime_events` | ✅ |
|
|||
|
|
| `GET /api/page-ai/pi/sessions` 路由注册 | ✅ |
|
|||
|
|
| `GET /api/page-ai/pi/sessions/{id}` 路由注册 | ✅ |
|
|||
|
|
| `GET /api/page-ai/pi/sessions/{id}/events` 路由注册 | ✅ |
|
|||
|
|
| list_sessions 按 pi_lab profile + pi acp_runtime 过滤 | ✅ |
|
|||
|
|
|
|||
|
|
### P2 — Receipt 与 patch 入库 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| migration v9 新增 `ai_tool_events / ai_file_patches` | ✅ |
|
|||
|
|
| SQLite 与 Turso/libSQL store 均实现 append/list | ✅ |
|
|||
|
|
| Pi tool receipt 默认写 control-plane | ✅ |
|
|||
|
|
| 成功 patch 关联写入 `ai_file_patches` | ✅ |
|
|||
|
|
| JSONL 仅在 control-plane 写失败时作为 debug fallback | ✅ |
|
|||
|
|
| deny reason、diff summary、file version、citation count 可查询 | ✅ |
|
|||
|
|
| receipt 与 patch 按当前用户隔离 | ✅ |
|
|||
|
|
|
|||
|
|
### P3 — AI 管理中心与管理员模型写管理 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| `/admin/ai` 路由与管理员鉴权 | ✅ |
|
|||
|
|
| `/user/ai` 路由与用户鉴权 | ✅ |
|
|||
|
|
| 账户菜单有独立 AI 管理入口 → `/admin/ai` 或 `/user/ai` | ✅ |
|
|||
|
|
| AI 管理页面 SSR 渲染 OpenHub-like 左侧分页与多 section | ✅ |
|
|||
|
|
| Access Scopes 只读展示(无 POST/PUT/DELETE、无写表单) | ✅ |
|
|||
|
|
| Sessions & Receipts 显示真实 Pi session、receipt、patch 数量 | ✅ |
|
|||
|
|
| Providers & Models 管理写操作 | ✅ |
|
|||
|
|
| `/user/ai` 用户可操作设置 | ❌ |
|
|||
|
|
|
|||
|
|
### 独立入口保留检查
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| OpenHub `/page-ai/openhub/ai` | ✅ |
|
|||
|
|
| OpenHub admin guard 路由 | ✅ |
|
|||
|
|
| OpenHub status API | ✅ |
|
|||
|
|
| Pi Lab shell `/page-ai/pi` | ✅ |
|
|||
|
|
| Pi Lab event stream `GET /api/page-ai/pi/events` | ✅ |
|
|||
|
|
| Pi Lab start/send/abort 路由 | ✅ |
|
|||
|
|
|
|||
|
|
### P4 — 工具、Skills/MCP 管理 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `GET/PUT /api/ai-admin/settings` 原子策略端点 | ✅ |
|
|||
|
|
| 模型 provider、allowed models、角色模型与 failover 写入 | ✅ |
|
|||
|
|
| MNote-owned tools allow/ask/deny 写入 | ✅ |
|
|||
|
|
| Skill 添加、描述、启停、删除 | ✅ |
|
|||
|
|
| MCP transport/command/url/network/secret refs 写入 | ✅ |
|
|||
|
|
| MCP 强制 facade-only 与 sandbox | ✅ |
|
|||
|
|
| 刷新后配置持久存在 | ✅ |
|
|||
|
|
| effective API 投影模型、Skills、MCP | ✅ |
|
|||
|
|
|
|||
|
|
### P5 — 逐用户 AI 配置 ✅
|
|||
|
|
|
|||
|
|
| 检查项 | 通过 |
|
|||
|
|
|---|---|
|
|||
|
|
| OpenHub `UserManagement`、模型/工具/Skill 权限实现已核验 | ✅ |
|
|||
|
|
| `GET /api/ai-admin/users` 用户列表 | ✅ |
|
|||
|
|
| `GET/PUT /api/ai-admin/users/{user_id}/settings` | ✅ |
|
|||
|
|
| 用户可独立选择管理员允许的模型和默认模型 | ✅ |
|
|||
|
|
| 用户工具策略只能相对全局降权 | ✅ |
|
|||
|
|
| 用户 Skill/MCP 只能在全局启用目录中开关 | ✅ |
|
|||
|
|
| 普通用户登录后的 effective API 应用 override | ✅ |
|
|||
|
|
| allowed roots 仍只来自 `directory_grants` | ✅ |
|
|||
|
|
| 用户抽屉采用 OpenHub-like 分组:模型按 provider、工具按 risk、Skill/MCP 开关、目录只读跳统一授权页 | ✅ |
|
|||
|
|
|
|||
|
|
## 后续项
|
|||
|
|
|
|||
|
|
| 项 | 状态 | 说明 |
|
|||
|
|
|---|---|---|
|
|||
|
|
| `/user/ai` 用户可操作偏好 | 未实现 | 当前只读 effective config,不能提升管理员权限 |
|
|||
|
|
| LightRAG source/index/status 写管理 | 未实现 | 继续使用唯一 knowledge provider 与现有 facade |
|
|||
|
|
| provider/skill/MCP 专用规范化表 | 未实现 | 当前原子策略存入 `ai_policies.model_policy_json`;出现独立查询、授权或生命周期需求时迁移 |
|
|||
|
|
|
|||
|
|
## 浏览器证据
|
|||
|
|
|
|||
|
|
- Pi Lab 原生抽屉:`tmp/7-71-pi-lab-browser-final.png`
|
|||
|
|
- AI 管理页:`tmp/7-71-ai-admin-final.png`
|
|||
|
|
- 模型写管理:`tmp/7-71-ai-admin-openhub-like-ui-final/models.png`
|
|||
|
|
- Skills/MCP 写管理:`tmp/7-71-ai-admin-openhub-like-ui-final/skills-mcp.png`
|
|||
|
|
- 逐用户 AI 配置:`tmp/7-71-ai-admin-openhub-like-ui-final/users.png`
|
|||
|
|
- 管理页运行时摘要:会话 1、回执 3、文件补丁 1
|
|||
|
|
- Pi Lab 截图可见真实 mock 回复、citation、diff、abort,且 OpenHub 默认入口仍独立存在
|
|||
|
|
- `mnote-e2e` 通过 control-plane `role=admin` 进入管理员模式;浏览器验收用 dev seed 临时确保测试账号为 admin
|
|||
|
|
- OpenHub 的 MCP 实际为用户工作区 `.opencode/mcp` 文件展示,并非 Admin per-user override;MNote 采用更严格的管理员注册 + 用户启停 + facade/sandbox 模型
|
|||
|
|
|
|||
|
|
## 验证命令
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 静态 smoke(只读代码审计,无需启动服务器)
|
|||
|
|
node scripts/task-ai-management-control-plane-static-smoke.js
|
|||
|
|
MNOTE_AI_ADMIN_OUTPUT_DIR=tmp/7-71-ai-admin-openhub-like-ui-final \
|
|||
|
|
node scripts/task-ai-management-browser-smoke.js
|
|||
|
|
node scripts/task-pi-lab-static-smoke.js
|
|||
|
|
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo check -p mnote-web
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane ai_tool_events
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane ai_file_patches
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p control-plane migrations
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web ai_settings
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web page_ai_pi
|
|||
|
|
CARGO_TARGET_DIR=/tmp/mnote-7-71-target cargo test -p mnote-web ai_admin
|
|||
|
|
|
|||
|
|
# 运行时验证(需要 mnote-web 运行于 localhost:3000)
|
|||
|
|
# curl -s http://localhost:3000/api/ai-settings/effective | jq '{source: .sourceOfTruth, models: [.models[].id], rootsCount: (.allowedRoots | length)}'
|
|||
|
|
# curl -s http://localhost:3000/api/ai-settings/access-scopes | jq '.sourceOfTruth'
|
|||
|
|
# curl -s http://localhost:3000/api/ai-admin/access-scopes | jq '.sourceOfTruth'
|
|||
|
|
# curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/admin/ai
|
|||
|
|
# curl -s -o /dev/null -w '%{http_code}\n' http://localhost:3000/user/ai
|
|||
|
|
```
|