Persist PageTree expand state via control-plane view-state and align chevron/DOM with restored expansion; keep Sidex-style shallow page-tree scan and drop the unused recursive scanner that only added cargo noise. Add password vault workbench routes/runtime/skill/CLI, split page_ai_pi into a module package, and retire Hermes/ACP/OpenHub recycle + root harness evidence from the index while gitignoring recycle and local diag dumps. Archive superseded design/bugs docs under old/, point architecture at ARCHITECTURE.md, and refresh smokes for Pi S1–S7, vault, and editor regressions so the working tree can stay clean.
25 KiB
[recycle] 7-61 [process] Yuxi reference: middleware tool composition, extensions entry, knowledge settings UI, and local dashboard v1
2026-06-28 覆盖说明:本文中 Hermes / LightRAG 相关实现口径已部分退为 legacy。仍可参考 Yuxi 的 middleware、extensions 入口和 dashboard 信息架构,但当前 MNote 知识库 / agent 主线以 OpenHub / opencode / WeKnora 为准。
创建时间:2026-06-13
当前状态:
PROCESSOwner: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.mdCURRENT_ARCHITECTURE.mddesign/07-ai/done/7-50-lightrag-knowledge-rag-provider-v1.mddesign/07-ai/done/7-57-yuxi-reference-ai-run-config-knowledge-facade-v1.mddesign/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.mddesign/03-rust-web/reference/3-23-sidebar-local-folder-resource-runtime-followup-v1.mddesign/10-review/done/16-mnote-web-runtime-module-maintainability-checklist-v1.md
1. 第一结论
Yuxi 有六个工程模式值得 MNote 借鉴,但不适合整体搬移:
- 中间件分层工具组合:Hermes tool manifest 当前是扁平 Vec,每次新增能力(knowledge base、skills、MCP、filesystem、subagent、summary)都在同一个 manifest 函数中线性追加。Yuxi 的 middleware 模式把每种能力作为独立层,按需组合。
- 扩展管理统一入口:当前 MNote 的 Skills/MCP/Knowledge Base/Tools 入口分散在 settings、Page AI settings、侧边栏等不同位置。Yuxi 的
ExtensionsView用 tab 统一管理所有扩展。 - 知识库详情设置页:当前 LightRAG settings 较薄,只有 source directory 和 basic status。Yuxi 的
DataBaseInfoView提供了文件管理、检索配置、图谱配置、评估等完整详情页。 - 流式事件状态机规范化:当前 Hermes SSE/WS 事件处理分散在多个 consumer(sidebar runtime、document adapter、Page AI sidebar)。Yuxi 的
handleStreamChunk是单一状态机,覆盖 init→loading→stream_event→finished/interrupted/error 全生命周期。 - 本地 Dashboard:当前 MNote 没有本地可观测性面板。Yuxi 的 Dashboard 提供了 agent run 调用量、token 消耗、知识库检索次数、工具调用频率等可视化。
- 虚拟路径安全:当前
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 模式:
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<Value>,约 30+ 个工具在一个函数中线性追加。新增 knowledge_rag、skills、context、block、onlyoffice 等工具时,每次都在同一个 manifest 函数末尾追加,没有按能力域分组。
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 模块,每个模块自声明工具和能力:
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<Value> 和 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 中统一),按权限分组:
设置
├── 通用
├── 外观
├── 编辑器
├── 扩展 ← 新增
│ ├── 知识库(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:
- 文件管理面板:展示已 ingest 文件列表、解析状态(parsing/chunking/indexing/done/error)、文件类型图标、最后更新时间
- 检索测试面板:输入 query → 直接调
/api/knowledge-rag/search→ 展示 top-K 结果 + citation preview + 来源文件 + 相关度 - 检索参数配置:search mode(local/global/hybrid/naive/mix)、top_k、相似度阈值(expose LightRAG
QueryParam可配置项) - 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:
// 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:
- Agent Run 统计(基于 7-57 run journal):最近 N 天 run 次数、平均耗时、成功/失败/中断分布
- Token 消耗(基于 run journal 中的 token usage):按 agent、按日期维度
- 知识库状态(基于 LightRAG status bridge):已索引文件数、总 chunk 数、最近 ingest 时间
- Skills/MCP 健康:已安装 skill 数、MCP 连接状态
数据源优先级:
- Agent run 统计:SQLite control-plane
agent_runs表(7-57 已建) - Token 消耗:从 run journal 中提取
- 知识库状态:LightRAG
/statusAPI + MNote status bridge - Skills/MCP:Hermes workspace 配置 + Rust manifest
不新增:
- 多用户统计(local-first 不需要)
- 实时推送更新(10 分钟 TTL + 手动刷新即可)
- 独立的时序数据库
3.6 虚拟路径安全加固
Yuxi 模式:
沙盒路径的关键安全设计:
# 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 中加固:
- Agent 可见路径使用虚拟前缀:agent 通过
mnote://workspace/、mnote://uploads/等虚拟路径引用文件,MNote 在 tool 边界做映射 - Run 级临时目录隔离:每个 agent run 有独立
mnote://runs/{run_id}/outputs/,不污染 workspace - 路径穿越防护:所有 agent 发来的路径必须在 allowed roots 内,且经过
canonicalize+starts_with双重校验 - 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_*工具
- A2a.
- A3. 每个 registry 暴露
pub fn tools() -> Vec<Value>+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) - 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打开对应资源
- C3a. 输入框 + 搜索按钮 → 调
- 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 配置)
- 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. 前端:卡片 + 简易柱状图(按天分布)
- E2a. 后端:
- E3. Token 消耗卡片
- E3a. 后端:从
agent_runs表提取 token usage 汇总(总 token、按 agent 分组) - E3b. 前端:数值卡片(本周消耗 / 总计)
- E3a. 后端:从
- E4. 知识库状态卡片
- E4a. 后端:代理 LightRAG
/status+ MNote status bridge,返回文件数、chunk 数、最近 ingest 时间 - E4b. 前端:数值卡片 + 状态灯
- E4a. 后端:代理 LightRAG
- E5. Skills/MCP 健康卡片
- E5a. 后端:从 Hermes workspace 配置 + Rust manifest 汇总
- E5b. 前端:列表 + 状态灯
- E6. 所有卡片使用 10 分钟 TTL + 手动刷新按钮,不做实时推送
- 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 页面均可正常访问