Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3283,6 +3283,17 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
}
}

// CRITICAL FIX: Explicitly mark ALL tool_use blocks as non-partial after finalization.
// This prevents race conditions where tools might still have partial=true if:
// - toolUseIndex was undefined during finalization (tool already removed from tracking)
// - finalizeStreamingToolCall returned null but tool exists in assistantMessageContent
// Without this, the first tool in a parallel batch could be presented twice.
for (const block of this.assistantMessageContent) {
if ((block.type === "tool_use" || block.type === "mcp_tool_use") && block.partial) {
block.partial = false
}
}

// IMPORTANT: Capture partialBlocks AFTER finalizeRawChunks() to avoid double-presentation.
// Tools finalized above are already presented, so we only want blocks still partial after finalization.
const partialBlocks = this.assistantMessageContent.filter((block) => block.partial)
Expand Down
Loading