8.0 KiB
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.md、design/07-ai/done/7-4-page-ai-hermes-panel-execution-checklist-v1.mdHermes Web UI 参考:
packages/client/src/api/hermes/plugins.ts、packages/client/src/api/hermes/skills.ts、packages/server/src/services/hermes/plugins.ts、packages/server/src/services/hermes/chat-run-socket.ts2026-05-16 口径补充:本文定义的是页面 AI 最小可用工具合同。
mnote.page.save只作为页面级兜底写入工具,不再代表长期精确块编辑方案;页面/块级 AI 工具体系以design/07-ai/process/7-9-page-block-ai-tooling-roadmap-v1.md为后续规划依据。
1. 总边界
- Hermes 看到的工具名必须是
mnote.*,不是mnote-cli、Next route 或前端私有函数。 - plugin 内部可以临时调用
mnote-cliJSON 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.updateOptions。runtimeSupport !== "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。