Hermes Dashboard 协议参考
这一页列出 Hermes Dashboard 适配器(@volcengine/chatkit/adapters/hermes-gateway)在 tui_gateway 上读写的字段,以及它们怎么变成 ChatKit 的消息、片段和轮次。接入写法见 Hermes Dashboard;API server 入口见 Hermes。
传输
一轮怎么认定
Hermes 的事件不带轮次编号。prompt.submit 固定带 queued: true,适配器按返回的 status 认定哪些事件属于这一轮:
读到 message.complete 或 error 时这一轮结束,之后的事件不再进这一轮。
tui_gateway 是 Hermes 内部接口,随版本变化。本页按 Hermes 0.20.0 安装版的 tui_gateway 源码与实测核对;升级后以 wire.types.ts 为准重新核对。完整的方法与事件见 hermes-agent 的 tui_gateway/。
发出的请求
transformInput 收到默认请求体 { text, images? },返回完整请求体:
附件只接受 MIME 为 image/*、来源为内联的图片;其他附件不发请求,抛出 cause.code 为 UNSUPPORTED_ATTACHMENT 的错误。
读取的事件
片段规则(实时与历史相同):
message.complete 的 usage、reasoning,tool.start 的 args_text,tool.complete 的 duration_s、summary、todos、inline_diff、result_text 等字段适配器不读;这些事件属于这一轮,可在 transformOutput 里从原始事件取。tool.start / tool.complete 是否推送受 Hermes 的 display.tool_progress 配置影响(clarify 工具总会推送)。
没有内置处理的事件
连接把一个会话的事件交给两处:
不带 session_id(或为空)的事件,以及属于本连接没有 resume 过的会话的事件,连接不交给任何一处;需要时接入方自行连接 Dashboard。
阻塞请求不回答时,工具会等到超时。用 listen 拿到后经 connection.request 回答(参数是 request_id 加 password / value / text):
在这一轮的回答里显示中途说明:
刷新加载历史时,适配器从消息行合成与实时同形的事件逐条交给 transformOutput(context.source 为 history,带这一轮的 runId 与 messageId,session_id 是持久编号):思考、正文各一条 reasoning.delta、message.delta(整段内容),工具一条 tool.start(只有 tool_id、name)与一条 tool.complete(tool_id、name、result),每轮收尾一条 message.complete。message.interim 等其它事件不在历史里,上面这张卡片刷新后不会还原;要还原就从回放里有的事件生成。
审批与追问
Hermes 推送的请求(只列读取的字段):
交互请求放在工具片段的 metadata['chatkit.interaction'] 上,用 getHermesGatewayInteraction(part) 读取:
回答:connection.respond({ sessionId, requestId, response }),审批给 choices 里的一项,追问给答案文本。
历史
GET api/sessions/{id}/messages 返回 { session_id, messages, pagination },适配器只读 messages;404 当作空历史。每一行读取:
历史不保留:轮次是否被中断或失败、被中断那一轮的思考与部分正文、审批记录、追加指令、用户消息里的图片。进行中的轮次在结束前不写进历史。同一会话有别的客户端同时写入时,按顺序对应可能错位。
编号
结束与错误
结束时:正文与思考去掉末尾空白,等待中的交互变为 cancelled;没正常完成时,还在执行的工具标为 cancelled。
断线时,所有等待中的请求失败,正在读的轮次收到 HermesGatewayClosedError,由 Core 标记连接中断,不认定执行结束;适配器不支持续接,执行结果以之后的历史为准。listen 的监听按下文自动重新订阅。connection.close() 结束全部正在读的轮次,之后的请求都失败。连接内部异常经 onError(kind, error) 报告(frame、listener、listen),没给时打到控制台。
listen 断线重连
连接断开(或这个会话的订阅单独结束)时,有 listen 监听的会话:
- 监听先收到
{ kind: 'connection', status: 'disconnected' }; - 连接按退避自动重连并重新订阅(重新取 token、建连并
session.resume,live 编号会变):第一次等reconnect.minDelayMs(缺省 1000),之后翻倍,最多等reconnect.maxDelayMs(缺省 30000); - 订阅恢复后收到
{ kind: 'connection', status: 'reconnected' }。断线期间的事件不会补发,需要时自行补拉状态(如重新取一次 REST 历史)。
每次重新订阅失败经 onError('listen', error) 报告,之后继续重试。取消全部监听或调用 close() 后停止;连接选项 reconnect: false 关闭自动重连(仍会收到 disconnected)。正在进行的一轮不续接,仍由会话层经历史确认终态。
示例
一轮带工具调用的事件(节选,session_id 为 live 编号):
得到 assistant:{runId},片段依次为 reasoning:0、tool:call_1(completed)、text:1(查到了),这一轮完成。
同一轮写进历史后的行:
片段编号与实时相同;页面重新加载后这一轮的 runId 为 hermes-row:1。