|
|
@@ -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
|
|
|
}
|
|
|
@@ -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)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -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
|
|
|
}
|
|
|
@@ -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)
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -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) {
|
|
|
// If there is content to update then it will complete and
|
|
|
// update `this.userMessageContentReady` to true, which we
|
|
|
// `pWaitFor` before making the next request.
|