# 7-61 [process] Yuxi reference: middleware tool composition, extensions entry, knowledge settings UI, and local dashboard v1 > 创建时间:2026-06-13 > > 当前状态:`PROCESS` > > Owner:07-ai / 03-rust-web / Hermes tools / Page AI settings / Knowledge RAG UI / Dashboard > > 上位设计:`design/07-ai/done/7-57-yuxi-reference-ai-run-config-knowledge-facade-v1.md` > > 本稿是 7-57 的补充,覆盖 7-57 未涉及的 Yuxi 参考领域。 > > 参考代码: > - `reference-code/Yuxi/backend/package/yuxi/agents/middlewares/`(中间件分层组合) > - `reference-code/Yuxi/backend/package/yuxi/agents/base.py`(Agent 基类 + checkpointer) > - `reference-code/Yuxi/web/src/views/ExtensionsView.vue`(扩展统一入口) > - `reference-code/Yuxi/web/src/views/DataBaseInfoView.vue`(知识库详情页) > - `reference-code/Yuxi/web/src/views/DashboardView.vue`(Dashboard 可观测性) > - `reference-code/Yuxi/web/src/composables/useAgentStreamHandler.js`(流式事件状态机) > - `reference-code/Yuxi/backend/package/yuxi/agents/backends/sandbox/paths.py`(虚拟路径安全) > > 上位依据: > - `ARCHITECTURE.md` > - `CURRENT_ARCHITECTURE.md` > - `design/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.md` > - `design/07-ai/done/7-57-yuxi-reference-ai-run-config-knowledge-facade-v1.md` > - `design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md` > - `design/03-rust-web/reference/3-23-sidebar-local-folder-resource-runtime-followup-v1.md` > - `design/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md` ## 1. 第一结论 Yuxi 有六个工程模式值得 MNote 借鉴,但不适合整体搬移: 1. **中间件分层工具组合**:Hermes tool manifest 当前是扁平 Vec,每次新增能力(knowledge base、skills、MCP、filesystem、subagent、summary)都在同一个 manifest 函数中线性追加。Yuxi 的 middleware 模式把每种能力作为独立层,按需组合。 2. **扩展管理统一入口**:当前 MNote 的 Skills/MCP/Knowledge Base/Tools 入口分散在 settings、Page AI settings、侧边栏等不同位置。Yuxi 的 `ExtensionsView` 用 tab 统一管理所有扩展。 3. **知识库详情设置页**:当前 LightRAG settings 较薄,只有 source directory 和 basic status。Yuxi 的 `DataBaseInfoView` 提供了文件管理、检索配置、图谱配置、评估等完整详情页。 4. **流式事件状态机规范化**:当前 Hermes SSE/WS 事件处理分散在多个 consumer(sidebar runtime、document adapter、Page AI sidebar)。Yuxi 的 `handleStreamChunk` 是单一状态机,覆盖 init→loading→stream_event→finished/interrupted/error 全生命周期。 5. **本地 Dashboard**:当前 MNote 没有本地可观测性面板。Yuxi 的 Dashboard 提供了 agent run 调用量、token 消耗、知识库检索次数、工具调用频率等可视化。 6. **虚拟路径安全**:当前 `WorkspacePath` 校验较松散。Yuxi 的 sandbox paths 有 `validate_thread_id` + `relative_to` 防穿越、虚拟路径前缀隔离、按 thread/user 分层。 这些都属于 MNote 现有主线的 enhancer,不改变底层(Hermes ACP / Reasonix / LightRAG / Rust SSR),不引入新存储或新 agent 框架。 ## 2. 非目标 - 不引入 LangGraph / DeepAgents 作为 agent runtime。 - 不复制 Yuxi 的 Milvus / Neo4j / Postgres 存储体系。 - 不把 Vue/Ant Design 前端模式迁入 Rust SSR / browser runtime。 - 不改变 LightRAG 作为唯一知识库 provider 的定位。 - 不新增定时轮询刷新。 - 不改变 local-first 普通 Markdown 编辑主路径。 - 不改变 7-57 已完成的 run journal / agent descriptor / knowledge facade 成果。 ## 3. 六个借鉴领域详析 ### 3.1 中间件分层工具组合 **Yuxi 模式**: ```python class ChatbotAgent(BaseAgent): async def get_graph(self, context=None, **kwargs): middlewares = [ create_agent_filesystem_middleware(...), # 文件系统 save_attachments_to_fs, # 附件落地 KnowledgeBaseMiddleware(), # 知识库检索 SkillsMiddleware(), # Skills 注入 create_subagent_task_middleware(context), # 子智能体 summary_middleware, # 上下文压缩 TodoListMiddleware(...), # 任务列表 PatchToolCallsMiddleware(), # 工具调用修复 ModelRetryMiddleware(max_retries=2), # 模型重试 ] return create_agent(model=..., tools=..., middleware=middlewares, ...) ``` 每个中间件是独立类/函数,按声明顺序构成 agent 的能力栈。新增能力只需新增一个 middleware,不改动 agent 核心流程。 **MNote 当前状态**: `manifest.rs` 中 Hermes tool manifest 是扁平 `Vec`,约 30+ 个工具在一个函数中线性追加。新增 knowledge_rag、skills、context、block、onlyoffice 等工具时,每次都在同一个 manifest 函数末尾追加,没有按能力域分组。 ```rust pub fn manifest() -> Value { let tools = annotate_tools_with_capabilities(vec![ skill_read_tool(), context_snapshot_tool(), // ... 30+ tools available_tool("mnote.artifact.create_summary", ...), ]); // ... } ``` **借鉴方向**: 不是引入 Python 式 class middleware,而是把 Rust manifest 按能力域拆成独立 registry 模块,每个模块自声明工具和能力: ```text hermes_tools/ manifest.rs → 顶层装配,组合各 registry registry/ context_registry.rs → context.* 工具组 doc_registry.rs → mnote.doc.* 工具组 block_registry.rs → mnote.block.* 工具组 page_registry.rs → mnote.page.* 工具组 knowledge_rag_registry.rs → mnote.knowledge_rag.* 工具组 skill_registry.rs → mnote.skill.* 工具组 mindmap_registry.rs → mindmap.* 工具组 onlyoffice_registry.rs → onlyoffice.* 工具组 artifact_registry.rs → mnote.artifact.* 工具组 ``` 每个 registry 暴露 `pub fn tools() -> Vec` 和 `pub fn capabilities() -> Vec<&'static str>`。manifest 只负责装配和 capability annotation。Agent descriptor 可以按 capability 选择性包含工具组。 ### 3.2 扩展管理统一入口 **Yuxi 模式**: `ExtensionsView.vue` 用一个 tab 组件统一管理四种扩展: ``` 智能体扩展 ├── 知识库(管理员可见) ├── 工具(管理员可见) ├── MCP(管理员可见) └── Skills(所有用户可见) ``` 每种扩展是独立子组件,通过 tab 切换懒加载。URL query 参数持久化当前 tab,刷新后不丢失。 **MNote 当前状态**: - Skills 入口:Page AI settings → Skills 子面板 - Knowledge base 入口:settings → 资料库 settings - MCP:Hermes MCP 配置在 Hermes workspace settings - Tools:无独立管理入口,Hermes tool manifest 是编译期静态 这四个入口分散在不同 settings surface,用户需要记住去哪找。 **借鉴方向**: 在 settings 页面增加"扩展"tab(或在现有 settings IA 中统一),按权限分组: ```text 设置 ├── 通用 ├── 外观 ├── 编辑器 ├── 扩展 ← 新增 │ ├── 知识库(LightRAG 资料库管理) │ ├── Skills(已安装 + 可用) │ ├── MCP 服务器 │ └── Agent 工具状态(只读能力清单) ├── AI(Hermes / Reasonix 配置) └── 关于 ``` 第一阶段不要求完整 CRUD,先做只读能力清单 + 已安装 Skills/MCP 状态展示 + 知识库详情入口。URL hash 持久化当前 tab。 ### 3.3 知识库详情设置页 **Yuxi 模式**: `DataBaseInfoView.vue` 是知识库详情页,子 tab 包括: - **文件管理**:文件夹树、上传、解析状态跟踪(pending/processing/done/error)、批量删除、文件预览 - **检索测试**:输入 query → 展示检索结果 + 相似度分数 + 来源文件 - **检索配置**:向量/BM25/混合检索模式选择、TopK、相似度阈值、BM25 权重 - **图谱配置**:实体抽取 schema、关系类型约束 - **评估**:检索质量评估、问答对测试 - **设置**:名称、描述、嵌入模型、分块策略、共享配置 **MNote 当前状态**: LightRAG settings 较薄,只有: - source directory 配置 - ingest 触发按钮 - 基本状态灯(indexed / pending) - OCR 开关 **借鉴方向**: 在不改变 LightRAG provider 的前提下,增强 knowledge base settings UI: 1. **文件管理面板**:展示已 ingest 文件列表、解析状态(parsing/chunking/indexing/done/error)、文件类型图标、最后更新时间 2. **检索测试面板**:输入 query → 直接调 `/api/knowledge-rag/search` → 展示 top-K 结果 + citation preview + 来源文件 + 相关度 3. **检索参数配置**:search mode(local/global/hybrid/naive/mix)、top_k、相似度阈值(expose LightRAG `QueryParam` 可配置项) 4. **Ingest 状态跟踪**:LightRAG 后台完成状态通过现有 status bridge/backoff 同步到 UI,展示每个文件的 stage 和 error 不新增: - 分块策略 UI(由 LightRAG 管) - 图谱 schema 编辑(由 LightRAG 管) - 嵌入模型切换(由 LightRAG 管) ### 3.4 流式事件状态机规范化 **Yuxi 模式**: `useAgentStreamHandler.js` 的 `handleStreamChunk` 是一个规范的状态机: ``` ┌─────────────────────────────────────────────┐ │ stream start │ └─────────────────┬───────────────────────────┘ │ ┌────────────▼────────────┐ │ init │ ← 建立 request_id 绑定 │ → replyLoadingVisible │ └────────────┬────────────┘ │ ┌────────────▼────────────┐ │ loading │ ← message_delta / tool_call_delta │ → push msgChunks │ └────────────┬────────────┘ │ ┌────────────▼────────────┐ │ stream_event │ ← tool-started / tool-finished │ → 关联 tool_call_id │ agent_state (todos/uploads) └────────────┬────────────┘ │ ┌────────────▼────────────┐ │ finished / interrupted │ ← terminal │ / error / approval │ └──────────────────────────┘ ``` 关键设计点: - 每种 status 有明确的过渡规则 - `stream_event` 中的 `tool-finished` 通过 `tool_call_id` 关联到对应 AI 消息 - `agent_state` 事件同步 todos/uploads 等运行时状态 - 中断(approval/interrupted)有独立的恢复路径 **MNote 当前状态**: Hermes SSE/WS 事件处理分散在多个 consumer: - `sidebar-page-ai-runtime.js` 处理 Page AI 面板的流式回复 - `document-editor-adapter-runtime.js` 处理编辑器内的 agent 交互 - 每个 consumer 有自己的事件解析和状态管理 **借鉴方向**: 不是引入 Vue composable,而是在 browser runtime 中抽出一个共享的 `AgentStreamEventRouter`: ```javascript // rust/crates/mnote-web/browser/agent-stream-event-router.js const EVENT_STATES = { INIT: 'init', LOADING: 'loading', STREAM_EVENT: 'stream_event', FINISHED: 'finished', INTERRUPTED: 'interrupted', ERROR: 'error', APPROVAL_REQUIRED: 'approval_required', }; function createAgentStreamRouter({ onDelta, onToolCall, onToolResult, onAgentState, onTerminal }) { return function routeEvent(event) { switch (event.status) { case EVENT_STATES.INIT: // 建立 request_id ↔ message 绑定 break; case EVENT_STATES.LOADING: // 判断 message_delta / tool_call_delta → onDelta / onToolCall break; case EVENT_STATES.STREAM_EVENT: // tool-started / tool-finished → onToolResult // agent_state → onAgentState break; case EVENT_STATES.FINISHED: case EVENT_STATES.INTERRUPTED: case EVENT_STATES.ERROR: onTerminal(event); break; case EVENT_STATES.APPROVAL_REQUIRED: // 中断等待用户确认 break; } }; } ``` Page AI sidebar runtime 和 document editor adapter 都消费同一个 router,各自提供自己的 `onDelta`/`onToolCall`/`onTerminal` 回调。 ### 3.5 本地 Dashboard **Yuxi 模式**: Dashboard 包含: - **调用统计**:按时间线的 agent run 次数、成功/失败率 - **用户活跃度**:DAU/MAU、会话时长 - **AI 智能体分析**:各 agent 调用量排行 - **工具调用监控**:各 tool 被调用次数、耗时 - **知识库使用情况**:检索次数、文件数、chunk 数 **MNote 当前状态**:无 Dashboard。 **借鉴方向**: 为 local-first 场景做最小 Dashboard: 1. **Agent Run 统计**(基于 7-57 run journal):最近 N 天 run 次数、平均耗时、成功/失败/中断分布 2. **Token 消耗**(基于 run journal 中的 token usage):按 agent、按日期维度 3. **知识库状态**(基于 LightRAG status bridge):已索引文件数、总 chunk 数、最近 ingest 时间 4. **Skills/MCP 健康**:已安装 skill 数、MCP 连接状态 数据源优先级: - Agent run 统计:SQLite control-plane `agent_runs` 表(7-57 已建) - Token 消耗:从 run journal 中提取 - 知识库状态:LightRAG `/status` API + MNote status bridge - Skills/MCP:Hermes workspace 配置 + Rust manifest 不新增: - 多用户统计(local-first 不需要) - 实时推送更新(10 分钟 TTL + 手动刷新即可) - 独立的时序数据库 ### 3.6 虚拟路径安全加固 **Yuxi 模式**: 沙盒路径的关键安全设计: ```python # 1. ID 安全校验 _SAFE_ID_RE = re.compile(r"^[A-Za-z0-9_-]+$") def validate_thread_id(thread_id: str) -> str: if not _SAFE_ID_RE.match(value): raise ValueError("thread_id contains invalid characters") # 2. 虚拟路径前缀隔离 def get_virtual_path_prefix() -> str: return "/" + VIRTUAL_PATH_PREFIX.strip("/") # /sandbox-v1 # 3. 路径穿越防护 def resolve_virtual_path(thread_id, virtual_path, *, uid): # 必须从虚拟前缀开始 # 用 relative_to 校验不穿越 base_dir # 4. 按 thread/user 分层 # workspace/ → 用户级共享 # uploads/ → 线程级 # outputs/ → 线程级 ``` **MNote 当前状态**: `WorkspacePath` 主要通过 `allowed_roots` 做目录白名单校验,但没有: - 线程级隔离(同一用户的多个 agent run 共享同一文件系统视图) - 虚拟路径前缀(agent 直接看到宿主机真实路径) - 正则 ID 校验 **借鉴方向**: 不是引入 Yuxi 的 Python sandbox,而是在 Rust `WorkspacePath` / `AiAccessScope` 中加固: 1. **Agent 可见路径使用虚拟前缀**:agent 通过 `mnote://workspace/`、`mnote://uploads/` 等虚拟路径引用文件,MNote 在 tool 边界做映射 2. **Run 级临时目录隔离**:每个 agent run 有独立 `mnote://runs/{run_id}/outputs/`,不污染 workspace 3. **路径穿越防护**:所有 agent 发来的路径必须在 allowed roots 内,且经过 `canonicalize` + `starts_with` 双重校验 4. **Attachments 目录**:agent 上传/生成的附件落 `mnote://attachments/{run_id}/`,与 workspace 文件明确分开 第一阶段只加固现有 `AiAccessScope` + `allowed_roots`,不改变 agent 现有文件操作语义。 ## 4. 执行优先级 | 批次 | 内容 | 优先级 | 预计影响面 | |------|------|--------|-----------| | **Batch A** | Hermes tool registry 模块化拆分 | 中 | manifest.rs 重构,不改变 API | | **Batch B** | 扩展管理 settings 入口 + 能力清单 | 高 | settings UI,不改变后端 | | **Batch C** | LightRAG 知识库详情页(文件管理 + 检索测试 + 检索参数) | 高 | knowledge-rag settings UI + 少量 API | | **Batch D** | AgentStreamEventRouter 抽共享 | 中 | browser runtime 重构,不改变 API | | **Batch E** | 本地 Dashboard 最小版 | 低 | 新页面 + SQLite 查询 | | **Batch F** | WorkspacePath 虚拟路径安全加固 | 低 | AiAccessScope 增强,agent tool 适配 | ## 5. Checklist ### Batch A:Hermes tool registry 模块化拆分 - [ ] A1. 在 `hermes_tools/` 下创建 `registry/` 子目录 - [ ] A2. 把 `manifest.rs` 中工具按能力域拆到独立 registry 模块 - [ ] A2a. `context_registry.rs`:`context_snapshot`、`context_read_current_page`、`context_resolve_target` - [ ] A2b. `doc_registry.rs`:`doc_fetch`、`doc_find`、`doc_markdown_edit`、`doc_apply_block_ops`、`doc_plan_update` - [ ] A2c. `block_registry.rs`:`block_fetch`、`block_replace`、`block_insert_after`、`block_delete`、`block_move_after` - [ ] A2d. `page_registry.rs`:`page_get`、`page_save`、`page_update_title`、`page_update_options` - [ ] A2e. `knowledge_rag_registry.rs`:`knowledge_rag_status`、`knowledge_rag_query`、`knowledge_rag_section_context`、`knowledge_rag_open_reference` - [ ] A2f. `skill_registry.rs`:`skill_read`、`skill_*` - [ ] A2g. `mindmap_registry.rs`:`mindmap_fetch`、`mindmap_apply_ops`、`mindmap_create_from_outline` - [ ] A2h. `onlyoffice_registry.rs`:所有 `onlyoffice_*` 工具 - [ ] A2i. `artifact_registry.rs`:`artifact_*` 工具 - [ ] A3. 每个 registry 暴露 `pub fn tools() -> Vec` + `pub fn capability_names() -> &[&str]` - [ ] A4. `manifest.rs` 改为装配层:收集各 registry 的 tools + 统一 capability annotation - [ ] A5. `cargo test -p mnote-web hermes_tool_manifest --lib` 通过 - [ ] A6. Agent descriptor smoke 验证 manifest 返回的工具列表与拆分前一致(`scripts/task557-page-ai-agent-descriptor-smoke.js`) ### Batch B:扩展管理 settings 入口 - [ ] B1. 在 settings 页面增加"扩展"tab,路由 `/settings?tab=extensions` - [ ] B2. 扩展 tab 包含子面板:知识库、Skills、MCP、Agent 工具 - [ ] B3. 知识库子面板:展示 LightRAG 当前状态 + 已索引文件数 + "管理"按钮 → 跳转知识库详情 - [ ] B4. Skills 子面板:展示已安装 skill 列表(名称、版本、状态、来源) - [ ] B5. MCP 子面板:展示已配置 MCP 服务器列表(名称、URL、连接状态) - [ ] B6. Agent 工具子面板:从 `/api/page-ai/agent-descriptors` 读取能力清单,只读展示 - [ ] B7. URL query 参数持久化当前子 tab(`&ext=knowledge|skills|mcp|tools`) - [x] B8. 登录态浏览器验证:settings → 扩展 tab,切换子面板,刷新后 tab 不丢失 ### Batch C:LightRAG 知识库详情页 - [ ] C1. 新增知识库详情页路由 `/knowledge-base` - [ ] C2. 文件管理面板 - [ ] C2a. 展示已 ingest 文件列表(文件名、类型图标、大小、状态灯、最后更新时间) - [ ] C2b. 状态灯映射:pending/parsing/chunking/indexing/done/error,每 30s 有界刷新(来自 status bridge) - [ ] C2c. 文件删除按钮(调 `mnote.knowledge_rag.delete` 或 LightRAG API) - [ ] C2d. 手动 re-index 按钮(单文件) - [ ] C3. 检索测试面板 - [ ] C3a. 输入框 + 搜索按钮 → 调 `/api/knowledge-rag/search` - [ ] C3b. 结果列表:citation preview + 来源文件 + 相关度分数 - [ ] C3c. 点击结果 → `open_reference` 打开对应资源 - [ ] C4. 检索参数配置面板 - [ ] C4a. search mode 下拉:local/global/hybrid/naive/mix - [ ] C4b. top_k 数字输入(1-100) - [ ] C4c. 相似度阈值滑块(0.0-1.0) - [ ] C4d. 保存到 `user_ui_preferences`(SQLite control-plane) - [ ] C5. Ingest 源目录管理:展示当前 source roots + 添加/移除(只改 MNote source registry,不动 LightRAG 配置) - [x] C6. 登录态浏览器验证:知识库详情页三个面板切换、检索测试真实返回结果、参数保存后刷新不丢失 ### Batch D:AgentStreamEventRouter 抽共享 - [ ] D1. 在 `rust/crates/mnote-web/browser/` 创建 `agent-stream-event-router.js` - [ ] D2. 定义标准事件类型 enum:init/loading/stream_event/finished/interrupted/error/approval_required - [ ] D3. 实现 `createAgentStreamRouter({ onDelta, onToolCall, onToolResult, onAgentState, onTerminal })` 工厂函数 - [ ] D4. `sidebar-page-ai-runtime.js` 改为消费 AgentStreamEventRouter - [ ] D5. `document-editor-adapter-runtime.js` 改为消费 AgentStreamEventRouter(如涉及编辑器内 agent 交互) - [ ] D6. 浏览器 smoke 回归:Page AI 对话、tool call 展示、中断恢复、finished 状态均正常 - [ ] D7. `scripts/task*-page-ai-*.js` 相关 smoke 通过 ### Batch E:本地 Dashboard 最小版 - [ ] E1. 新增 `/dashboard` 路由 + 页面壳 - [ ] E2. Agent Run 统计卡片 - [ ] E2a. 后端:`GET /api/dashboard/agent-run-stats?days=7` → 返回 run 总数、成功/失败/中断分布、按 agent 分组 - [ ] E2b. 前端:卡片 + 简易柱状图(按天分布) - [ ] E3. Token 消耗卡片 - [ ] E3a. 后端:从 `agent_runs` 表提取 token usage 汇总(总 token、按 agent 分组) - [ ] E3b. 前端:数值卡片(本周消耗 / 总计) - [ ] E4. 知识库状态卡片 - [ ] E4a. 后端:代理 LightRAG `/status` + MNote status bridge,返回文件数、chunk 数、最近 ingest 时间 - [ ] E4b. 前端:数值卡片 + 状态灯 - [ ] E5. Skills/MCP 健康卡片 - [ ] E5a. 后端:从 Hermes workspace 配置 + Rust manifest 汇总 - [ ] E5b. 前端:列表 + 状态灯 - [ ] E6. 所有卡片使用 10 分钟 TTL + 手动刷新按钮,不做实时推送 - [x] E7. 登录态浏览器验证:Dashboard 页面展示各卡片数据 ### Batch F:WorkspacePath 虚拟路径安全加固 - [ ] F1. 在 `AiAccessScope` 中增加 `run_id` 字段 - [ ] F2. 实现 `AgentVirtualPath` 类型:`mnote://workspace/`、`mnote://outputs/{run_id}/`、`mnote://uploads/{run_id}/` - [ ] F3. 在 Hermes tool 边界做虚拟路径 ↔ 真实路径映射(`resolve_agent_path` / `to_agent_virtual_path`) - [ ] F4. 路径穿越防护:`canonicalize` + `starts_with(allowed_root)` 双重校验 - [ ] F5. Run 级临时目录:每个 agent run 开始时创建 `mnote://outputs/{run_id}/`,run 结束时清理 - [ ] F6. Agent tool smoke 验证:agent 只能访问 allowed roots 内文件,路径穿越被拒绝 ## 6. 与现有设计的关系 | 现有设计 | 本稿关系 | |----------|---------| | 7-57 Batch A (run journal) | 本稿 Batch E (Dashboard) 消费 run journal 做统计 | | 7-57 Batch B (agent descriptor) | 本稿 Batch B 的工具清单面板消费 descriptor | | 7-50 (LightRAG provider) | 本稿 Batch C 是其 UI 增强 | | 7-18 (agent file editing) | 本稿 Batch F 加固其 AiAccessScope | | 3-23 (sidebar local folder runtime) | 本稿 Batch B/C 在 settings 中增加入口 | | 7-38 (Page AI sidebar owner split) | 本稿 Batch D 是 sidebar runtime 的事件路由重构 | ## 7. 风险 - **Batch A 重构 manifest**:如果工具名或 capability annotation 在拆分中漂移,会导致 agent descriptor 不一致。必须用 smoke 对比拆分前后的 manifest JSON。 - **Batch C 检索参数**:LightRAG `QueryParam` 的字段可能随版本变化。MNote 透传用户配置时应做字段白名单,未知字段忽略。 - **Batch D 事件路由重构**:如果 browser runtime 中的事件格式在不同 consumer 间有细微差异(例如 Page AI 用 `message_id`,editor 用 `msg_id`),统一 router 时需要兼容映射。 - **Batch E Dashboard**:SQLite `agent_runs` 表可能膨胀。后续需要 TTL 清理策略,当前阶段保留最近 30 天。 - **Batch F 虚拟路径**:agent 端(Hermes / Reasonix)需要能处理 `mnote://` 前缀,或 MNote 在 tool 边界双向映射。第一阶段先只映射,不要求 agent 原生理解虚拟路径。 ## 8. 验证基线 - `cargo test -p mnote-web --lib` 全绿 - `scripts/task557-page-ai-agent-descriptor-smoke.js` 通过 - `scripts/task529-knowledge-rag-citation-resource-tab-smoke.js` 通过 - `scripts/task530-knowledge-rag-page-ai-final-answer-smoke.js` 通过 - 新增 smoke:`scripts/task561-extensions-settings-smoke.js`(Batch B+C) - 新增 smoke:`scripts/task561-dashboard-smoke.js`(Batch E) - 登录态浏览器验证:settings 扩展 tab、知识库详情页、Dashboard 页面均可正常访问