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
21 changes: 15 additions & 6 deletions src/core/tools/NewTaskTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,31 @@ export class NewTaskTool extends BaseTool<"new_task"> {
// Preserve the current mode so we can resume with it later.
task.pausedModeSlug = (await provider.getState()).mode ?? defaultModeSlug

// For native protocol, set the pending tool call ID BEFORE starting the subtask.
// This prevents a race condition where the subtask completes (during the delay
// in startSubtask) before we set the ID, which would cause completeSubtask to
// not push the tool_result, breaking the API conversation structure.
if (toolProtocol === "native" && toolCallId) {
task.pendingNewTaskToolCallId = toolCallId
}

const newTask = await task.startSubtask(unescapedMessage, todoItems, mode)

if (!newTask) {
// Clear the pending ID since the subtask wasn't created
if (toolProtocol === "native" && toolCallId) {
task.pendingNewTaskToolCallId = undefined
}
pushToolResult(t("tools:newTask.errors.policy_restriction"))
return
}

// For native protocol, defer the tool_result until the subtask completes.
// For native protocol with toolCallId, don't push tool_result here.
// The actual result (including what the subtask accomplished) will be pushed
// by completeSubtask. This gives the parent task useful information about
// what the subtask actually did.
if (toolProtocol === "native" && toolCallId) {
task.pendingNewTaskToolCallId = toolCallId
// Don't push tool_result here - it will come from completeSubtask with the actual result.
// The task loop will stay alive because isPaused is true (see Task.ts stack push condition).
} else {
// The task loop will stay alive because isPaused is true (see Task.ts stack push condition).
if (toolProtocol !== "native" || !toolCallId) {
// For XML protocol, push the result immediately (existing behavior)
pushToolResult(
`Successfully created new task in ${targetMode.name} mode with message: ${unescapedMessage} and ${todoItems.length} todo items`,
Expand Down
Loading