bug(claude-code): planner step only captures 1 turn despite using tools #439

Closed
opened 2026-05-23 11:22:03 +00:00 by xiaoju · 0 comments
Owner

现象

uwf thread stepsolve-issue workflow 的 planner role 时,detail 里只记录了 1 turn(最终 assistant summary),toolCalls: null

但 planner 的输出包含真实的代码行号和函数签名(如 resolveWorkflowCasRef lines 120-147),说明 Claude Code 确实读了文件,只是中间的 tool use turns 没被捕获。

对比

Role numTurns Captured Turns Duration Output Tokens
planner 1 1 7.5s 522
developer 64 152 411s 20,272

Developer 的 turn 收集完全正常(152 turns with tool calls),但 planner 只有 1 turn。

可能原因

  1. stream-json --verbose 对短 session 的输出格式不同 — 如果 Claude Code 在单次 API call 内完成所有工作(server-side tool use?),stream 输出可能不包含中间 tool call 行
  2. parseClaudeCodeStreamOutput 解析逻辑丢失部分行 — 同一个 message.id 的 assistant message 拆成多行(text + tool_use),parser 可能只保留了最后一行
  3. Claude Code 的 num_turns 统计口径num_turns: 1 可能表示只有 1 次 user→assistant 交互,但内部可能有多次 tool call 在同一 turn 内
  4. Planner 真的只用了 1 turn — 靠 39K input context(prompt 里包含了大量代码上下文?)直接输出了 plan,没调工具

复现

uwf thread start DSYW9ZSBBA4F9 -p "Resolve issue #428 in repo uncaged/workflow"
uwf thread step <thread-id>  # planner step
uwf thread step-details <step-hash>  # check numTurns and turns array

调查方向

  1. claude-code.ts 里加 raw stdout dump,保存到文件,看 planner 的完整 NDJSON 输出
  2. 对比 planner vs developer 的 NDJSON 行数和结构差异
  3. 确认 parseClaudeCodeStreamOutput 是否正确处理了所有 stream-json 事件类型
  4. 验证是否存在 server-side tool use(不通过 stream 输出的 tool call)

相关代码

  • packages/workflow-agent-claude-code/src/session-detail.tsparseClaudeCodeStreamOutput()
  • packages/workflow-agent-claude-code/src/claude-code.tsspawnClaudeRun() + processClaudeOutput()

Thread 数据

  • Thread: 06F58NG0FJ6P4RFAAPK1XHZNY4
  • Planner step: 3S3JB8FNGNNNY (detail: 64EVQJ58X4RZ3)
  • Developer step: FTAM242AM2P2A (detail: CX4G8YWCE9RDA)

小橘 🍊(NEKO Team)

## 现象 用 `uwf thread step` 跑 `solve-issue` workflow 的 planner role 时,detail 里只记录了 **1 turn**(最终 assistant summary),`toolCalls: null`。 但 planner 的输出包含真实的代码行号和函数签名(如 `resolveWorkflowCasRef` lines 120-147),说明 Claude Code **确实读了文件**,只是中间的 tool use turns 没被捕获。 ## 对比 | Role | numTurns | Captured Turns | Duration | Output Tokens | |------|----------|---------------|----------|---------------| | planner | 1 | 1 | 7.5s | 522 | | developer | 64 | 152 | 411s | 20,272 | Developer 的 turn 收集完全正常(152 turns with tool calls),但 planner 只有 1 turn。 ## 可能原因 1. **`stream-json --verbose` 对短 session 的输出格式不同** — 如果 Claude Code 在单次 API call 内完成所有工作(server-side tool use?),stream 输出可能不包含中间 tool call 行 2. **`parseClaudeCodeStreamOutput` 解析逻辑丢失部分行** — 同一个 `message.id` 的 assistant message 拆成多行(text + tool_use),parser 可能只保留了最后一行 3. **Claude Code 的 `num_turns` 统计口径** — `num_turns: 1` 可能表示只有 1 次 user→assistant 交互,但内部可能有多次 tool call 在同一 turn 内 4. **Planner 真的只用了 1 turn** — 靠 39K input context(prompt 里包含了大量代码上下文?)直接输出了 plan,没调工具 ## 复现 ```bash uwf thread start DSYW9ZSBBA4F9 -p "Resolve issue #428 in repo uncaged/workflow" uwf thread step <thread-id> # planner step uwf thread step-details <step-hash> # check numTurns and turns array ``` ## 调查方向 1. 在 `claude-code.ts` 里加 raw stdout dump,保存到文件,看 planner 的完整 NDJSON 输出 2. 对比 planner vs developer 的 NDJSON 行数和结构差异 3. 确认 `parseClaudeCodeStreamOutput` 是否正确处理了所有 stream-json 事件类型 4. 验证是否存在 server-side tool use(不通过 stream 输出的 tool call) ## 相关代码 - `packages/workflow-agent-claude-code/src/session-detail.ts` — `parseClaudeCodeStreamOutput()` - `packages/workflow-agent-claude-code/src/claude-code.ts` — `spawnClaudeRun()` + `processClaudeOutput()` ## Thread 数据 - Thread: `06F58NG0FJ6P4RFAAPK1XHZNY4` - Planner step: `3S3JB8FNGNNNY` (detail: `64EVQJ58X4RZ3`) - Developer step: `FTAM242AM2P2A` (detail: `CX4G8YWCE9RDA`) 小橘 🍊(NEKO Team)
Sign in to join this conversation.
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#439