uwf-hermes: 从 Hermes session 文件读取 turn 数据,替代 ACP 流式重建 #519

Closed
opened 2026-05-25 14:13:15 +00:00 by xingyue · 0 comments
Owner

问题

uwf step showuwf step read 显示的 tool call 数据是错的:

  • name 变成了 ACP 的展示用 title(如 "terminal: export PATH=..."),不是真正的工具名
  • args 全是空字符串

根因

uwf-hermes 的 acp-client.tshandleToolCall 里从 ACP 的 session/update 通知重建 messages,但:

  1. ACP 协议没有 toolName 字段,只有 title(展示摘要),handleToolCall 把 title 当工具名用了
  2. Hermes 对常用工具不填 rawInput_POLISHED_TOOLSraw_input=None),导致 args 始终为空

这是 ACP 协议设计如此——它是为 IDE 展示设计的,不是为结构化数据还原设计的。

方案

不再从 ACP 流式 update 重建 messages,改为直接读 Hermes 的 session JSON 文件(~/.hermes/sessions/session_{sid}.json),那里面 tool_calls 是完整的 {function: {name, arguments}}

改动点

1. packages/workflow-agent-hermes/src/hermes.ts

storePromptResult 改为用 loadHermesSession(sessionId) 从文件读,不再用 ACP client 返回的 messages:

async function storePromptResult(
  store: Store,
  sessionId: string,
): Promise<{ detailHash: string }> {
  const session = await loadHermesSession(sessionId);
  if (session === null) {
    throw new Error(`Hermes session file not found: ${sessionId}`);
  }
  return storeHermesSessionDetail(store, session);
}

runPrompt 相应去掉 messages 解构。

2. packages/workflow-agent-hermes/src/acp-client.ts

删除 messages 收集相关逻辑:

  • pendingTools map
  • messages 数组
  • messageChunks / reasoningChunks 数组
  • handleToolCallhandleToolCallUpdateflushAssistantMessage 方法
  • handleAgentMessageChunkhandleAgentThoughtChunk 方法

只保留 text 提取(从最后的 agent_message_chunk 拼出 final text)。

prompt() 返回类型简化为 { text: string; sessionId: string }

3. 确保 write_json_snapshots 开启

Hermes 的 session JSON 文件受 sessions.write_json_snapshots 控制(默认 False)。uwf-hermes 运行时必须确保此配置开启。方案二选一:

  • acp-client.tsconnect 时通过环境变量传递(如果支持)
  • 在文档中要求用户在 ~/.hermes/config.yaml 中配置 sessions.write_json_snapshots: true

推荐后者,在 uwf-hermes README 里注明。

4. Session 重入兼容

Resume 场景下 session 文件包含所有轮次(旧 + 新),与之前 ACP client 累积 messages 的行为一致,无需特殊处理。

相关文件

  • packages/workflow-agent-hermes/src/acp-client.ts — ACP 客户端,messages 收集逻辑
  • packages/workflow-agent-hermes/src/hermes.tsstorePromptResult,调用入口
  • packages/workflow-agent-hermes/src/session-detail.tsloadHermesSession(已有,直接用)
  • packages/cli-workflow/src/commands/step.tsloadTurnDataTurnData 类型也需要增强,支持 role/toolCalls 展示(独立问题,可一并修)
## 问题 `uwf step show` 和 `uwf step read` 显示的 tool call 数据是错的: - `name` 变成了 ACP 的展示用 title(如 `"terminal: export PATH=..."`),不是真正的工具名 - `args` 全是空字符串 ### 根因 uwf-hermes 的 `acp-client.ts` 在 `handleToolCall` 里从 ACP 的 `session/update` 通知重建 messages,但: 1. **ACP 协议没有 `toolName` 字段**,只有 `title`(展示摘要),`handleToolCall` 把 title 当工具名用了 2. **Hermes 对常用工具不填 `rawInput`**(`_POLISHED_TOOLS` 设 `raw_input=None`),导致 args 始终为空 这是 ACP 协议设计如此——它是为 IDE 展示设计的,不是为结构化数据还原设计的。 ### 方案 不再从 ACP 流式 update 重建 messages,改为直接读 Hermes 的 session JSON 文件(`~/.hermes/sessions/session_{sid}.json`),那里面 `tool_calls` 是完整的 `{function: {name, arguments}}`。 ### 改动点 #### 1. `packages/workflow-agent-hermes/src/hermes.ts` `storePromptResult` 改为用 `loadHermesSession(sessionId)` 从文件读,不再用 ACP client 返回的 messages: ```typescript async function storePromptResult( store: Store, sessionId: string, ): Promise<{ detailHash: string }> { const session = await loadHermesSession(sessionId); if (session === null) { throw new Error(`Hermes session file not found: ${sessionId}`); } return storeHermesSessionDetail(store, session); } ``` `runPrompt` 相应去掉 `messages` 解构。 #### 2. `packages/workflow-agent-hermes/src/acp-client.ts` 删除 messages 收集相关逻辑: - `pendingTools` map - `messages` 数组 - `messageChunks` / `reasoningChunks` 数组 - `handleToolCall`、`handleToolCallUpdate`、`flushAssistantMessage` 方法 - `handleAgentMessageChunk`、`handleAgentThoughtChunk` 方法 只保留 `text` 提取(从最后的 agent_message_chunk 拼出 final text)。 `prompt()` 返回类型简化为 `{ text: string; sessionId: string }`。 #### 3. 确保 `write_json_snapshots` 开启 Hermes 的 session JSON 文件受 `sessions.write_json_snapshots` 控制(默认 False)。uwf-hermes 运行时必须确保此配置开启。方案二选一: - 在 `acp-client.ts` 的 `connect` 时通过环境变量传递(如果支持) - 在文档中要求用户在 `~/.hermes/config.yaml` 中配置 `sessions.write_json_snapshots: true` 推荐后者,在 uwf-hermes README 里注明。 #### 4. Session 重入兼容 Resume 场景下 session 文件包含所有轮次(旧 + 新),与之前 ACP client 累积 messages 的行为一致,无需特殊处理。 ### 相关文件 - `packages/workflow-agent-hermes/src/acp-client.ts` — ACP 客户端,messages 收集逻辑 - `packages/workflow-agent-hermes/src/hermes.ts` — `storePromptResult`,调用入口 - `packages/workflow-agent-hermes/src/session-detail.ts` — `loadHermesSession`(已有,直接用) - `packages/cli-workflow/src/commands/step.ts` — `loadTurnData` 和 `TurnData` 类型也需要增强,支持 role/toolCalls 展示(独立问题,可一并修)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#519