5.5 KiB
5.5 KiB
7-5 [done] Hermes client proxy 合同 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/chat.ts、packages/client/src/api/hermes/sessions.ts、packages/server/src/routes/hermes/proxy-handler.ts、packages/server/src/services/hermes/chat-run-socket.ts
1. 边界
- 浏览器只访问 mnote-web 同源
/api/hermes/client/*。 - Hermes API key / gateway token 只存在 mnote-web 服务端环境变量。
- mnote-web proxy 只做 auth、同源安全、页面上下文注入、trace 注入和错误码标准化。
- mnote-web proxy 不保存 Hermes session、message、tool event、usage、model 真相。
pageContext是 run 输入上下文,不是 Hermes session 的长期事实源。- 旧
/api/ai-agent/run在并存期只作为 legacy endpoint,不是新 Hermes 面板主代理。
2. 路由
GET /api/hermes/client/sessions
请求:
GET /api/hermes/client/sessions?workspaceId=ws_1&documentId=doc_1&limit=20
响应:
{
"ok": true,
"traceId": "trace_1",
"sessions": [
{
"sessionId": "mnote_doc_1_20260514",
"title": "当前页问答",
"preview": "请总结当前页面",
"messageCount": 2,
"toolCallCount": 1,
"updatedAt": 1778712000,
"model": "hermes-agent"
}
]
}
POST /api/hermes/client/sessions
请求:
{
"workspaceId": "ws_1",
"documentId": "doc_1",
"traceId": "trace_1",
"title": "当前页问答"
}
响应:
{
"ok": true,
"sessionId": "mnote_doc_1_trace_1",
"traceId": "trace_1",
"persistence": "hermes_on_first_run"
}
说明:Hermes Web UI 参考实现没有独立 session create HTTP route,客户端生成 session id,首次 run 时由 Hermes 持久化。mnote 保留本 route 是为了同源客户端合同稳定,但不得在 mnote 保存聊天历史。
GET /api/hermes/client/sessions/{session_id}
请求:
GET /api/hermes/client/sessions/mnote_doc_1_trace_1?workspaceId=ws_1&documentId=doc_1
响应:
{
"ok": true,
"sessionId": "mnote_doc_1_trace_1",
"traceId": "trace_1",
"messages": [
{
"messageId": "42",
"role": "assistant",
"content": "当前页标题是...",
"toolCallId": null,
"toolName": null,
"timestamp": 1778712000,
"reasoning": null
}
],
"usage": {
"inputTokens": 120,
"outputTokens": 30,
"totalTokens": 150
}
}
POST /api/hermes/client/runs
请求:
{
"workspaceId": "ws_1",
"documentId": "doc_1",
"sessionId": "mnote_doc_1_trace_1",
"message": "概括当前页面标题和第一段",
"model": "hermes-agent",
"pageContext": {
"title": "项目计划",
"outline": [],
"pageOptions": { "wideLayout": true }
},
"selectedBlockId": null,
"selectedText": null,
"traceId": "trace_1"
}
响应:
{
"ok": true,
"sessionId": "mnote_doc_1_trace_1",
"runId": "run_123",
"messageId": null,
"events": [],
"traceId": "trace_1"
}
GET /api/hermes/client/events/{run_id}
请求:
GET /api/hermes/client/events/run_123?sessionId=mnote_doc_1_trace_1
响应:text/event-stream
data: {"event":"message.delta","run_id":"run_123","session_id":"mnote_doc_1_trace_1","delta":"当前页"}
data: {"event":"run.completed","run_id":"run_123","session_id":"mnote_doc_1_trace_1","output":"当前页...","usage":{"input_tokens":120,"output_tokens":30,"total_tokens":150}}
POST /api/hermes/client/runs/{run_id}/abort
请求:
{
"workspaceId": "ws_1",
"documentId": "doc_1",
"sessionId": "mnote_doc_1_trace_1",
"traceId": "trace_1"
}
响应:
{
"ok": true,
"runId": "run_123",
"sessionId": "mnote_doc_1_trace_1",
"traceId": "trace_1",
"events": [
{ "event": "abort.started", "run_id": "run_123" }
]
}
GET /api/hermes/client/models
响应:
{
"ok": true,
"traceId": "trace_1",
"defaultModel": "hermes-agent",
"models": [
{ "id": "hermes-agent", "label": "Hermes Agent", "provider": "hermes" }
]
}
GET /api/hermes/client/tools
响应:
{
"ok": true,
"traceId": "trace_1",
"tools": [
{ "name": "mnote.page.get", "scope": "page.read", "schemaVersion": "mnote.hermes_tool.v1" }
]
}
3. 错误响应
统一错误体:
{
"ok": false,
"code": "hermes_client_unconfigured",
"message": "Hermes client proxy 未配置 upstream",
"traceId": "trace_1",
"requestId": "req_1"
}
稳定错误码:
hermes_client_unauthorized:未登录或缺少有效 mnote 会话。hermes_client_unconfigured:未配置MNOTE_WEB_HERMES_UPSTREAM_URL。hermes_client_bad_request:请求 JSON 或必要字段错误。hermes_client_upstream_unauthorized:Hermes upstream 拒绝服务端 token。hermes_client_upstream_rate_limited:Hermes upstream 429。hermes_client_upstream_unavailable:Hermes upstream 连接失败或 5xx。
4. 并存期规则
- 新页面 AI 面板只允许请求
/api/hermes/client/*。 /api/ai-agent/run保留为 legacy guard,不再承载 Hermes 页面 AI 主链。provider=hermes不再通过旧/api/ai-agent/run表达。- 所有新 smoke 应断言页面 AI 主链没有
/api/ai-agent/run请求。