mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: race condition in new_task tool for native protocol (#9655)
The pendingNewTaskToolCallId was being set AFTER startSubtask() returned. However, startSubtask() contains a 500ms delay during which the subtask could complete. If the subtask completed during this window, completeSubtask() would be called before pendingNewTaskToolCallId was set, causing it to fall through to the XML protocol path and add a text message instead of a proper tool_result block, breaking the API conversation structure. This fix moves the pendingNewTaskToolCallId assignment to happen BEFORE calling startSubtask(), ensuring the ID is set before the subtask starts. If the subtask creation fails, the pending ID is cleared.
This commit is contained in:
parent
400d0cd183
commit
d2d311e501
1 changed files with 15 additions and 6 deletions
|
|
@ -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`,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue