fix: parallel tool_use ghost content_block_delta (index error)

resToAnthHandleFuncArgsDone used state.ContentBlockIndex directly
instead of looking up from OutputIndexToBlockIdx like
resToAnthHandleFuncArgsDelta does. When multiple tool_calls arrive
in parallel and arguments come as a packed .done (no prior delta),
the second+ tool would emit content_block_delta on an index that
was never content_block_start'ed, causing Claude Code to report
"Content block not found".

Fix: resolve block index from OutputIndexToBlockIdx, and skip the
delta if the block is already closed or the index doesn't match
the current open block.

Closes #4193
This commit is contained in:
蔡及
2026-07-15 00:44:09 +08:00
parent da85cc7e47
commit 4f3b5110e2
@@ -452,10 +452,20 @@ func resToAnthHandleFuncArgsDone(evt *ResponsesStreamEvent, state *ResponsesEven
raw = string(sanitized)
}
idx := state.ContentBlockIndex
// 从事件的 OutputIndex 解析正确的 block index,与 resToAnthHandleFuncArgsDelta 对齐
blockIdx, ok := state.OutputIndexToBlockIdx[evt.OutputIndex]
if !ok {
blockIdx = state.ContentBlockIndex
}
// 如果 block 已关闭(ContentBlockIndex 已越过它),说明 arguments 已通过 delta 流式发完,不再补发
if !state.ContentBlockOpen || blockIdx != state.ContentBlockIndex {
return nil
}
events := []AnthropicStreamEvent{{
Type: "content_block_delta",
Index: &idx,
Index: &blockIdx,
Delta: &AnthropicDelta{
Type: "input_json_delta",
PartialJSON: raw,