Skip to content
Merged
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
54 changes: 49 additions & 5 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2473,12 +2473,14 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
// Finalize the streaming tool call
const finalToolUse = NativeToolCallParser.finalizeStreamingToolCall(event.id)

// Get the index for this tool call
const toolUseIndex = this.streamingToolCallIndices.get(event.id)

if (finalToolUse) {
// Store the tool call ID
;(finalToolUse as any).id = event.id

// Get the index and replace partial with final
const toolUseIndex = this.streamingToolCallIndices.get(event.id)
if (toolUseIndex !== undefined) {
this.assistantMessageContent[toolUseIndex] = finalToolUse
}
Expand All @@ -2491,6 +2493,25 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {

// Present the finalized tool call
presentAssistantMessage(this)
} else if (toolUseIndex !== undefined) {
// finalizeStreamingToolCall returned null (malformed JSON or missing args)
// We still need to mark the tool as non-partial so it gets executed
// The tool's validation will catch any missing required parameters
const existingToolUse = this.assistantMessageContent[toolUseIndex]
if (existingToolUse && existingToolUse.type === "tool_use") {
existingToolUse.partial = false
// Ensure it has the ID for native protocol
;(existingToolUse as any).id = event.id
}

// Clean up tracking
this.streamingToolCallIndices.delete(event.id)

// Mark that we have new content to process
this.userMessageContentReady = false

// Present the tool call - validation will handle missing params
presentAssistantMessage(this)
}
}
}
Expand Down Expand Up @@ -2611,12 +2632,14 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
// Finalize the streaming tool call
const finalToolUse = NativeToolCallParser.finalizeStreamingToolCall(event.id)

// Get the index for this tool call
const toolUseIndex = this.streamingToolCallIndices.get(event.id)

if (finalToolUse) {
// Store the tool call ID
;(finalToolUse as any).id = event.id

// Get the index and replace partial with final
const toolUseIndex = this.streamingToolCallIndices.get(event.id)
if (toolUseIndex !== undefined) {
this.assistantMessageContent[toolUseIndex] = finalToolUse
}
Expand All @@ -2629,6 +2652,25 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {

// Present the finalized tool call
presentAssistantMessage(this)
} else if (toolUseIndex !== undefined) {
// finalizeStreamingToolCall returned null (malformed JSON or missing args)
// We still need to mark the tool as non-partial so it gets executed
// The tool's validation will catch any missing required parameters
const existingToolUse = this.assistantMessageContent[toolUseIndex]
if (existingToolUse && existingToolUse.type === "tool_use") {
existingToolUse.partial = false
// Ensure it has the ID for native protocol
;(existingToolUse as any).id = event.id
}

// Clean up tracking
this.streamingToolCallIndices.delete(event.id)

// Mark that we have new content to process
this.userMessageContentReady = false

// Present the tool call - validation will handle missing params
presentAssistantMessage(this)
}
}
}
Expand Down Expand Up @@ -2898,9 +2940,11 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
this.assistantMessageContent = parsedBlocks
}

// Only present partial blocks that were just completed (from XML parsing)
// Native tool blocks were already presented during streaming, so don't re-present them
if (partialBlocks.length > 0 && partialBlocks.some((block) => block.type !== "tool_use")) {
// Present any partial blocks that were just completed
// For XML protocol: includes both text and tool_use blocks parsed from the text stream
// For native protocol: tool_use blocks were already presented during streaming via
// tool_call_partial events, but we still need to present them if they exist (e.g., malformed)
if (partialBlocks.length > 0) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this change fixes XML and the other one fixes native tool calls?

// If there is content to update then it will complete and
// update `this.userMessageContentReady` to true, which we
// `pWaitFor` before making the next request.
Expand Down
Loading