14 KiB
7-39 Page AI agent selector / context authorization settings v1
创建时间:2026-05-28 状态:
done来源:用户反馈:旧 Page AI UI 信息过载;“编辑当前文件 / 工作区任务”模式难以区分;应参考 Cline 在聊天输入区选择 agent,并在设置里按 agent 拆分配置;共性设置包含授权区域,且授权区域应按用户保存到 SQLite。
1. 背景
当前 Page AI sidebar 已能接 Hermes / Reasonix ACP、run target snapshot、changed files 审计和 SQLite directory grant。但 UI 仍把 agent、profile、runtime、skills、history、gateway、工具参数和错误解释混在一个抽屉中。
这导致两个问题:
- 用户真正要做的只是“选择 agent + 勾选要发给 AI 的上下文地址”,但现有 UI 暴露了太多 Hermes/ACP 运行细节。
- “编辑当前文件”和“工作区任务”作为主模式不稳定:本地 Markdown、打开资源、选区、文件夹和 changed files 都可能参与同一轮请求,按模式分流反而会误导。
因此后续 Page AI 主线应从“模式切换”改为“agent 选择 + contextRefs 勾选 + SQLite 授权区域”的结构。
2. 参考对照
2.1 Cline
可借鉴模型:
- 聊天输入区附近直接选择当前 agent / provider,让用户在提问前完成路由决策。
- 设置页按 agent/provider 拆分,只把模型、profile、API、能力开关等差异配置放在各自页面。
- 共性配置只放所有 agent 都需要理解的内容,例如上下文、授权、审计、历史保留。
只作参考实现:
- Cline 的 VSCode extension 状态和 provider 配置模型不能直接搬到 MNote;MNote 的授权区域必须继续走 SQLite control-plane,而不是浏览器 localStorage 或扩展全局状态。
不适合 MNote:
- 不把“工作区 root”当作天然可读写范围。MNote 必须基于
directory_grants/AiAccessScope/ allowed roots 显式授权。
2.2 Sidex / VSCode workbench
可借鉴模型:
- 资源、编辑器、工作区和最近修改项应以可选引用表达,而不是把 UI 分成互斥大模式。
- Explorer / editor / panel 可以共享同一份打开资源快照,但不把 UI 层选择变成新的树或页面真相。
只作参考实现:
- VSCode / Sidex 的工作台布局、tab model、context key 可以作为交互参考;MNote 的真实对象边界仍由 Rust kernel projection、local-first source 和 control-plane 决定。
不适合 MNote:
- 不把 VSCode extension host 或工作台状态当成 MNote 的资源生命周期真相。
3. 产品决策
3.1 主聊天面
主聊天面只保留四类默认可见元素:
- 当前 agent 选择器:位于输入框下方或紧邻输入框,默认可快速切换
Hermes、Reasonix、Chat-only,未来可扩展其他 agent。 - ContextRefs 选择器:用勾选 chip / popover 选择要发送的地址,例如当前页、当前选区、当前打开资源、指定文件、指定文件夹、最近 changed files。
- 输入框和发送/停止按钮。
- 简短状态:只显示“可用 / 需要授权 / 正在运行 / 失败”,不默认显示 gateway、profile、tool trace、参数 JSON。
“编辑当前文件 / 工作区任务”不再作为主模式。它们退化为 contextRefs 的预设组合:
- 编辑当前文件:勾选当前页或当前文件 + 必要的写权限 allowed root。
- 工作区任务:勾选一个或多个文件夹 / changed files / 打开资源 + 必要的读写授权。
3.2 共性设置
共性设置只保留所有 agent 共享的配置:
- 授权区域:来自 SQLite
directory_grants,按当前用户隔离;展示 root、权限、递归、来源、状态。 - 默认上下文勾选:保存到 SQLite
user_ui_preferences,按用户、workspace、source 隔离。 - changed files 展示策略:默认收起,只显示摘要;需要时展开路径/hash/mtime/actor。
- 隐私与审计:是否记录 local agent audit、是否展示工具细节、是否允许发送选区/页面摘要。
共性设置不放 Hermes profile、Reasonix skill、provider API key、模型 preset 等 agent 差异项。
3.3 Agent 设置
设置页按 agent 拆分:
- Hermes:profile、Hermes 设置入口、Hermes/ACP runtime 兼容提示、Hermes 专属 tool 开关。
- Reasonix:ACP runtime、Reasonix skill 只读/可用状态、Reasonix 专属能力说明。
- Chat-only:模型或 provider 选择、是否允许读取 contextRefs;默认不请求文件写权限。
- 未来 agent:通过 registry 增加
agentId、显示名、能力、设置 schema、运行入口。
每个 agent 只能保存自身差异设置。默认 agent、默认 contextRefs 和授权区域仍属于共性设置。
4. 数据与合同
4.1 SQLite 使用边界
优先复用现有 control-plane:
directory_grants:每用户授权区域真相。用于生成 allowed roots,不能由前端本地状态代替。user_ui_preferences:每用户 UI 偏好。用于默认 agent、contextRefs 默认勾选、授权区域排序/最近使用、UI 密度、changed files 默认折叠状态。
建议 preference scope / key:
scope = "ai.common",key = "default_agent_id"scope = "ai.common",key = "context_refs.default_selected"scope = "ai.common",key = "allowed_roots.default_selected"scope = "ai.common",key = "allowed_roots.order"scope = "ai.common",key = "changed_files.visibility"scope = "ai.agent.hermes",key = "profile_id"scope = "ai.agent.reasonix",key = "skill_panel_filter"scope = "ai.agent.chat_only",key = "model_id"
除非现有表无法表达这些键值,否则第一阶段不新增 SQLite 表。
4.2 请求合同草案
{
"agentId": "reasonix",
"message": "把选中的 Markdown 小节整理成 checklist",
"contextRefs": [
{
"kind": "current_page",
"documentId": "local:page:example",
"rootUri": "file:///mnt/Data1T/mnote"
},
{
"kind": "folder",
"rootUri": "file:///mnt/Data1T/mnote",
"relativePath": "design/07-ai"
}
],
"allowedRoots": [
{
"rootUri": "file:///mnt/Data1T/mnote",
"permission": "write",
"source": "sqlite_directory_grant"
}
],
"runTargetSnapshot": {
"version": "mnote.page_ai_run_target_snapshot.v1",
"source": "open_editors_snapshot"
},
"audit": true
}
合同要求:
agentId是主路由字段,不能再隐含在 Hermes profile 或 ACP runtime 里。contextRefs是用户勾选的上下文地址,不等同于授权。allowedRoots必须由 SQLite 授权区域和当前用户权限解析得到。runTargetSnapshot继续从OpenEditorsSnapshot冻结,防止 run 过程中 UI 切换导致目标漂移。
5. 旧 UI 精简规则
默认聊天面应移除或收敛:
- 顶部同时展示 Hermes/profile/model/gateway 的多重状态。
- 空态长解释、示例段落和“后端 AI 会话”等实现细节文案。
- Runtime 页默认暴露 gateway health、queue、tools、trace、audit JSON。
- Skills 页默认展示大量参数、来源和技术标签。
- 工具调用卡默认展示 args/result/raw trace。
- 输入框 placeholder 固定写“问 Hermes...”。
替代方式:
- 默认只显示 agent 名称、上下文 chips、运行状态和最终回答。
- 工具调用、changed files、audit、gateway、queue 进入“高级 / 调试”折叠区。
- 错误文案先给用户动作,例如“需要授权该文件夹”,再提供可展开技术详情。
- Hermes / Reasonix 的差异通过 agent selector 和 agent 设置页表达,不在聊天主面堆说明。
6. Checklist
Batch A - 现状冻结与视觉基线
- 截图记录当前 Page AI sidebar 默认聊天面、Agent、Runtime、Skills、History 页。
- 标注必须删除/折叠的冗余信息:profile/model/gateway、runtime queue、tool trace、长空态说明、Hermes 固定文案。
- 对照 Cline agent selector 和 Sidex/VSCode context/resource 模型,形成最小信息架构图。
- 验证:浏览器截图 + 本文档补充截图路径或 smoke 证据。
证据:旧 UI 基线截图在 tmp/task502-page-ai-baseline/01-chat.png、02-agent.png、03-skills.png、04-runtime.png、05-history.png;收敛后截图在 tmp/task502-page-ai-agent-selector-context-smoke/01-agent-selector-context.png。
Batch B - Agent registry 与主选择器
- 定义
agentIdregistry:hermes、reasonix、chat_only,包含显示名、能力、是否可写文件、设置页入口。 - 在聊天输入区附近增加 agent selector,替代“Hermes 固定入口”。
- 发送请求时 payload 显式包含
agentId,旧 Hermes/Reasonix ACP 路径保持兼容。 - 验证:node smoke 断言切换 agent 后 payload 和 UI badge 正确。
证据:rust/crates/mnote-web/browser/sidebar-page-ai-runtime.js 的 PAGE_AI_AGENT_REGISTRY;scripts/task502-page-ai-agent-selector-context-smoke.js 断言 hermes/reasonix/chat_only 和 run payload agentId=reasonix。
Batch C - ContextRefs 勾选器
- 定义
contextRefs类型:当前页、选区、当前打开资源、文件、文件夹、changed files。 - ContextRefs 从
OpenEditorsSnapshot、当前 selection 和授权目录解析,不新增第二套页面/树真相。 - “编辑当前文件 / 工作区任务”改为预设组合,不再作为主模式。
- 验证:浏览器 smoke 勾选/取消 contextRefs 后 payload 稳定。
证据:PAGE_AI_CONTEXT_REF_REGISTRY 覆盖 current_page/selection/active_editor/file/folder/changed_files;task502 断言取消 current_page 后 payload 不含 current_page/pageText/pageXml/contextBlocks,并保留 active_editor/folder/changed_files。
Batch D - SQLite per-user 授权区域
- 共性设置页展示当前用户的
directory_grants,支持按 read/write、recursive、source、status 展示。 - allowedRoots 只从当前用户 SQLite grant 解析;未授权目录必须提示授权,不允许前端绕过。
- 修复/补齐 Page AI 与 ACP session create 的授权路径一致性,确保已授权本地文件夹不会误报无权访问。
- 验证:Rust 定点测试覆盖不同用户 grant 隔离;浏览器 smoke 覆盖授权目录可用、未授权目录阻断。
证据:hermes_client.rs::enforce_local_ai_run_access 服务端按当前 actor 调 resolve_access 重算 allowedRoots;sqlite.rs::resolve_access_does_not_match_sibling_uri_prefix 修复 URI 前缀串扰;local_ai_run_access_* 覆盖 Alice/Bob 隔离与 chat_only read-only 降级;task502 验证授权 chip 来源为 sqlite_directory_grant。
Batch E - UI preference per-user 持久化
- 用
user_ui_preferences保存默认 agent、默认 contextRefs、授权区域排序/默认勾选、changed files 折叠策略。 - preference key 必须带 user/workspace/source/scope 边界。
- 不用 localStorage 作为长期真相;最多作为临时 UI cache。
- 验证:Rust/JS smoke 覆盖 Alice/Bob 设置隔离。
证据:ui_preferences.rs 支持 ai.common.* 与 ai.agent.*,并返回 aiPreferences;ui_preferences_api_persists_ai_preferences_per_user_and_workspace 验证 Alice/Bob 隔离;task502 捕获 PUT ai.common.default_agent_id 与 ai.common.context_refs.default_selected。
Batch F - Agent 分页设置
- 设置页拆为 Common / Hermes / Reasonix / Chat-only。
- Common 只放授权、默认 contextRefs、隐私/审计、changed files 显示策略。
- Hermes 只放 Hermes profile/upstream/tool 相关设置。
- Reasonix 只放 Reasonix ACP/skill 相关设置。
- Chat-only 默认不申请文件写权限。
- 验证:浏览器 smoke 检查不同 agent 设置页不串项。
证据:ensurePageAiDrawer 拆出 Common/Hermes/Reasonix/Chat-only/高级面板;task502 用真实浏览器检查 Common 不含 Hermes profile/ACP runtime,Hermes 不混 Reasonix,Reasonix 不混 Hermes,Chat-only 不混 ACP runtime。
Batch G - 旧 UI 冗余收敛
- 默认聊天面隐藏 gateway/model/profile 技术细节,只保留 agent badge 和简短状态。
- Runtime/Skills/History 收敛为高级/调试入口,默认不进入主聊天流。
- 工具调用卡默认只展示摘要;args/result/raw trace 需展开。
- changed files 默认摘要,展开后才显示路径/hash/mtime/actor。
- 验证:浏览器截图对比,确保主面没有冗余解释和技术噪音。
证据:sidebar-page-ai-runtime.js 默认标题状态改为 agent/授权/AI session,旧 Hermes session 与固定 问 Hermes 文案退出默认聊天面;task502 断言默认聊天面不含 问 Hermes/model.default/gateway:/Hermes profile;changed files 仍由 task453-local-folder-page-ai-changed-files-smoke.js 验证摘要与 dirty 阻断。
Batch H - 合同与回归
- 补最小 JS/Rust 合同注释或文档,说明
agentId + contextRefs + allowedRoots + runTargetSnapshot的边界。 - 保持 Hermes / Reasonix 旧 payload 兼容,必要时在 route 层做窄 adapter。
- 更新 Page AI smoke,覆盖 agent 切换、contextRefs、SQLite 授权、per-user preference、旧路径兼容。
- 运行
git diff --check、相关 Rust 定点测试、node smoke;涉及代码图修改后运行codegraph sync .。
证据:JS 合同注释位于 PAGE_AI_AGENT_REGISTRY 前;服务端兼容仍走 /api/hermes/client/runs 和 ACP profile/acpRuntime adapter;最终验证矩阵见本次执行汇报。
7. 非目标
- 不实现 Phase C 流式 apply / suggest review。
- 不把 local-first 普通 Markdown 编辑改回粗粒度
mnote.page.save。 - 不新增第二套树真相、页面真相、资源生命周期真相或授权真相。
- 不把 agent 设置写入浏览器 localStorage 作为长期存储。
- 不在本批次重构 Hermes / Reasonix agent 内部运行时。
8. 待确认产品点
- Agent selector 的精确位置:输入框下方一行,还是输入框左侧/上方 compact row。
- ContextRefs 默认勾选:是否默认包含当前页和当前选区,还是只默认当前页。
- Chat-only 是否允许读取文件夹摘要,或严格只允许聊天文本和显式勾选的页面摘要。
- 技术调试入口默认是否仅管理员可见,还是普通用户也可展开。