Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit e621c39

Browse files
committed
fix: prevent duplicated tool call rendering in parallel execution
Explicitly marks all tool_use blocks as non-partial after finalization to prevent race conditions where tools might still have partial=true. Fixes EXT-634
1 parent f389733 commit e621c39

1 file changed

Lines changed: 11 additions & 0 deletions

File tree

src/core/task/Task.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3283,6 +3283,17 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
32833283
}
32843284
}
32853285

3286+
// CRITICAL FIX: Explicitly mark ALL tool_use blocks as non-partial after finalization.
3287+
// This prevents race conditions where tools might still have partial=true if:
3288+
// - toolUseIndex was undefined during finalization (tool already removed from tracking)
3289+
// - finalizeStreamingToolCall returned null but tool exists in assistantMessageContent
3290+
// Without this, the first tool in a parallel batch could be presented twice.
3291+
for (const block of this.assistantMessageContent) {
3292+
if ((block.type === "tool_use" || block.type === "mcp_tool_use") && block.partial) {
3293+
block.partial = false
3294+
}
3295+
}
3296+
32863297
// IMPORTANT: Capture partialBlocks AFTER finalizeRawChunks() to avoid double-presentation.
32873298
// Tools finalized above are already presented, so we only want blocks still partial after finalization.
32883299
const partialBlocks = this.assistantMessageContent.filter((block) => block.partial)

0 commit comments

Comments
 (0)