fix: restore orchestrator subtask connection after VSCode restart

- Check both parentTask and parentTaskId in attemptCompletionTool to handle cases where the direct reference is lost
- Enhance finishSubTask to restore parent task from history when not in stack
- Add proper error handling and logging for parent task restoration

Fixes #8621
This commit is contained in:
Roo Code 2025-10-12 03:47:43 +00:00
parent 3a47c55a2e
commit fef9bb1d70
2 changed files with 31 additions and 4 deletions

View file

@ -95,7 +95,9 @@ export async function attemptCompletionTool(
TelemetryService.instance.captureTaskCompleted(cline.taskId)
cline.emit(RooCodeEventName.TaskCompleted, cline.taskId, cline.getTokenUsage(), cline.toolUsage)
if (cline.parentTask) {
// Check both parentTask (direct reference) and parentTaskId (persisted ID)
// This handles cases where VSCode was closed and the direct reference was lost
if (cline.parentTask || cline.parentTaskId) {
const didApprove = await askFinishSubTaskApproval()
if (!didApprove) {

View file

@ -482,12 +482,37 @@ export class ClineProvider
// This is used when a subtask is finished and the parent task needs to be
// resumed.
async finishSubTask(lastMessage: string) {
// Get the current task before removing it from the stack
const currentTask = this.getCurrentTask()
const parentTaskId = currentTask?.parentTaskId
// Remove the last cline instance from the stack (this is the finished
// subtask).
await this.removeClineFromStack()
// Resume the last cline instance in the stack (if it exists - this is
// the 'parent' calling task).
await this.getCurrentTask()?.completeSubtask(lastMessage)
// Check if there's a parent task in the stack
let parentTask = this.getCurrentTask()
// If no parent task in stack but we have a parentTaskId,
// we need to restore the parent task (happens when VSCode was closed)
if (!parentTask && parentTaskId) {
try {
// Restore the parent task from history
const { historyItem } = await this.getTaskWithId(parentTaskId)
parentTask = await this.createTaskWithHistoryItem(historyItem)
this.log(`[finishSubTask] Restored parent task ${parentTaskId} from history to receive subtask result`)
} catch (error) {
this.log(
`[finishSubTask] Failed to restore parent task ${parentTaskId}: ${error instanceof Error ? error.message : String(error)}`,
)
// Even if parent restoration fails, we should still show completion
// The user can manually resume the parent from task history
return
}
}
// Resume the parent task with the subtask result
await parentTask?.completeSubtask(lastMessage)
}
// Pending Edit Operations Management