Files
mnote/design/old/07-ai/done/7-6-mnote-hermes-plugin-tool-contract-v1.md
T
Agent Board b798f628ee chore: land tree view-state, vault, Pi module split, and repo hygiene
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.
2026-07-21 05:13:05 +08:00

8.4 KiB
Raw Blame History

[recycle] 7-6 [done] mnote Hermes plugin tool 合同 v1

更新时间:2026-05-14

上位依据:design/07-ai/done/7-3-page-ai-hermes-panel-and-mnote-plugin-v1.mddesign/07-ai/done/7-4-page-ai-hermes-panel-execution-checklist-v1.md

Hermes Web UI 参考:packages/client/src/api/hermes/plugins.tspackages/client/src/api/hermes/skills.tspackages/server/src/services/hermes/plugins.tspackages/server/src/services/hermes/chat-run-socket.ts

2026-05-16 口径补充:本文定义的是页面 AI 最小可用工具合同。mnote.page.save 只作为页面级兜底写入工具,不再代表长期精确块编辑方案;页面/块级 AI 工具体系路线图已归档到 design/07-ai/done/7-9-page-block-ai-tooling-roadmap-v1.md

2026-05-22 归档治理补充:旧 7-10 已移入 design/old/07-ai/process/7-10-page-block-ai-tooling-execution-checklist-v1.md,不再作为当前执行验收入口;7-14 也已移入 design/old/07-ai/process/7-14-local-first-ai-markdown-editing-convergence-v1.md。当前 AI 编辑 active 口径以 design/07-ai/process/7-18-local-first-agent-file-editing-control-plane-v1.md 为准,MNote 不再提供普通 Markdown 编辑工具。

1. 总边界

  • Hermes 看到的工具名必须是 mnote.*,不是 mnote-cli、Next route 或前端私有函数。
  • plugin 内部可以临时调用 mnote-cli JSON adapter,但这只是内部 adapter,不是长期 tool 名称。
  • Hermes plugin 不直接写 Convex;所有写入必须回到 Rust runtime / kernel。
  • mnote 只保存业务事实、audit、artifact、edge、page/body/title/options 结果,不保存 Hermes 聊天历史。
  • 所有 tool call 必须携带 sessionId/runId/toolCallId/traceId 便于串联 Hermes run 与 Rust command。

2. 统一入参

{
  "toolName": "mnote.page.get",
  "workspaceId": "ws_1",
  "documentId": "doc_1",
  "actorId": "user_1",
  "sessionId": "mnote_doc_1_trace_1",
  "runId": "run_123",
  "toolCallId": "call_123",
  "traceId": "trace_1",
  "idempotencyKey": "idem_123",
  "dryRun": false,
  "capabilityScope": ["page.read"],
  "args": {}
}

3. 统一出参

{
  "ok": true,
  "toolName": "mnote.page.get",
  "toolCallId": "call_123",
  "traceId": "trace_1",
  "result": {},
  "audit": {
    "effect": "read",
    "commandId": null,
    "workspaceId": "ws_1",
    "documentId": "doc_1"
  },
  "error": null
}

失败:

{
  "ok": false,
  "toolName": "mnote.page.save",
  "toolCallId": "call_123",
  "traceId": "trace_1",
  "result": null,
  "audit": {
    "effect": "none",
    "workspaceId": "ws_1",
    "documentId": "doc_1"
  },
  "error": {
    "code": "mnote_tool_permission_denied",
    "message": "当前用户没有页面写权限"
  }
}

4. 第一批工具 schema

mnote.page.get

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "includeBody": { "type": "boolean", "default": true },
    "includeOptions": { "type": "boolean", "default": true },
    "includeBlocks": { "type": "boolean", "default": true }
  }
}

成功:

{
  "ok": true,
  "toolName": "mnote.page.get",
  "toolCallId": "call_get_1",
  "traceId": "trace_1",
  "result": {
    "documentId": "doc_1",
    "workspaceId": "ws_1",
    "title": "项目计划",
    "bodySummary": "第一段...",
    "pageOptions": { "wideLayout": true },
    "blocks": [{ "id": "heading_1", "type": "heading", "text": "章节一" }]
  },
  "audit": { "effect": "read", "commandId": null }
}

失败:

{
  "ok": false,
  "toolName": "mnote.page.get",
  "toolCallId": "call_get_1",
  "traceId": "trace_1",
  "error": { "code": "mnote_tool_permission_denied", "message": "无页面读取权限" }
}

mnote.page.save

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "sessionId", "runId", "toolCallId", "traceId", "idempotencyKey", "dryRun", "content"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "content": { "type": "array" },
    "mode": { "type": "string", "enum": ["replace", "append"] },
    "idempotencyKey": { "type": "string" },
    "dryRun": { "type": "boolean" }
  }
}

成功:

{
  "ok": true,
  "toolName": "mnote.page.save",
  "toolCallId": "call_save_1",
  "traceId": "trace_1",
  "result": { "commandName": "page.body.save", "revision": 8 },
  "audit": { "effect": "write", "commandId": "page_body_save_trace_1" }
}

dryRun

{
  "ok": true,
  "toolName": "mnote.page.save",
  "toolCallId": "call_save_1",
  "traceId": "trace_1",
  "result": { "dryRun": true, "diff": [{ "op": "append", "blocks": 1 }] },
  "audit": { "effect": "dry_run", "commandId": null }
}

权限失败:

{
  "ok": false,
  "toolName": "mnote.page.save",
  "toolCallId": "call_save_1",
  "traceId": "trace_1",
  "error": { "code": "mnote_tool_permission_denied", "message": "无页面写权限" }
}

业务失败:

{
  "ok": false,
  "toolName": "mnote.page.save",
  "toolCallId": "call_save_1",
  "traceId": "trace_1",
  "error": { "code": "mnote_tool_conflict", "message": "页面版本冲突,需要刷新后重试" }
}

mnote.page.update_title

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "title", "sessionId", "runId", "toolCallId", "traceId", "idempotencyKey", "dryRun"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "title": { "type": "string", "minLength": 1 },
    "idempotencyKey": { "type": "string" },
    "dryRun": { "type": "boolean" }
  }
}

成功、dryRun、权限失败、业务失败响应形状同 mnote.page.save,成功 command 为 page.head.updateTitle

mnote.page.update_options

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "options", "sessionId", "runId", "toolCallId", "traceId", "idempotencyKey", "dryRun"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "options": {
      "type": "object",
      "properties": {
        "wideLayout": { "type": "boolean" },
        "smallText": { "type": "boolean" },
        "showToc": { "type": "boolean" },
        "protectEditing": { "type": "boolean" }
      },
      "additionalProperties": false
    },
    "idempotencyKey": { "type": "string" },
    "dryRun": { "type": "boolean" }
  }
}

成功、dryRun、权限失败、业务失败响应形状同 mnote.page.save,成功 command 为 page.layout.updateOptionsruntimeSupport !== "wired" 的字段必须返回 dryRun 警告或业务失败。

mnote.artifact.create_summary

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "summary", "sessionId", "runId", "toolCallId", "traceId", "idempotencyKey", "dryRun"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "summary": { "type": "string" },
    "idempotencyKey": { "type": "string" },
    "dryRun": { "type": "boolean" }
  }
}

成功:创建或更新当前页面唯一 summary node,并创建或确认 reference edge。

失败示例:

{
  "ok": false,
  "toolName": "mnote.artifact.create_summary",
  "toolCallId": "call_summary_1",
  "traceId": "trace_1",
  "error": { "code": "mnote_tool_idempotency_conflict", "message": "同一幂等键已用于不同 summary 内容" }
}

mnote.artifact.create_ai_note

入参:

{
  "type": "object",
  "required": ["workspaceId", "documentId", "content", "sessionId", "runId", "toolCallId", "traceId", "idempotencyKey", "dryRun"],
  "properties": {
    "workspaceId": { "type": "string" },
    "documentId": { "type": "string" },
    "content": { "type": "string" },
    "idempotencyKey": { "type": "string" },
    "dryRun": { "type": "boolean" }
  }
}

成功:每次创建独立 ai_note node,并创建 reference edge。

5. 权限、幂等与 dryRun

  • 权限校验点:登录、workspace member、页面读、页面写、artifact 写。
  • 同一 idempotencyKey 重试不得重复创建 artifact 或重复写正文。
  • dryRun=true 只能返回计划和 diff,不得写入。
  • 所有失败响应不得泄露无权限页面标题、正文或 artifact 内容。
  • 写工具返回的 audit.commandId 必须能追踪到 Rust runtime / kernel command。