mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: comprehensive orchestrator mode restoration for sub-tasks
- Enhanced resumePausedTask method with comprehensive mode restoration logic - Added mode restoration safety net in finishSubTask method - Improved mode validation and restoration in task resumption from history - Added error handling for interrupted sub-tasks with mode restoration - Ensures parent task mode is properly restored regardless of how sub-task ends Fixes #5747
This commit is contained in:
parent
d0452d0d5c
commit
53e264b968
2 changed files with 117 additions and 0 deletions
|
|
@ -763,6 +763,35 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
this.isPaused = false
|
||||
this.emit("taskUnpaused")
|
||||
|
||||
// Restore the mode that was active when this task was paused
|
||||
const provider = this.providerRef.deref()
|
||||
if (provider && this.pausedModeSlug) {
|
||||
try {
|
||||
const currentState = await provider.getState()
|
||||
const currentMode = currentState?.mode ?? defaultModeSlug
|
||||
|
||||
if (currentMode !== this.pausedModeSlug) {
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} restoring mode from '${currentMode}' to '${this.pausedModeSlug}'`,
|
||||
)
|
||||
|
||||
await provider.handleModeSwitch(this.pausedModeSlug)
|
||||
|
||||
// Delay to allow mode change to take effect
|
||||
await delay(500)
|
||||
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} successfully restored to '${this.pausedModeSlug}' mode`,
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} failed to restore mode to '${this.pausedModeSlug}': ${error}`,
|
||||
)
|
||||
// Continue execution even if mode restoration fails
|
||||
}
|
||||
}
|
||||
|
||||
// Fake an answer from the subtask that it has completed running and
|
||||
// this is the result of what it has done add the message to the chat
|
||||
// history and to the webview ui.
|
||||
|
|
@ -795,6 +824,35 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
modifiedClineMessages.splice(lastRelevantMessageIndex + 1)
|
||||
}
|
||||
|
||||
// Restore mode if this task was paused with a specific mode
|
||||
const provider = this.providerRef.deref()
|
||||
if (provider && this.pausedModeSlug && this.pausedModeSlug !== defaultModeSlug) {
|
||||
try {
|
||||
const currentState = await provider.getState()
|
||||
const currentMode = currentState?.mode ?? defaultModeSlug
|
||||
|
||||
if (currentMode !== this.pausedModeSlug) {
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} resuming from history - restoring mode from '${currentMode}' to '${this.pausedModeSlug}'`,
|
||||
)
|
||||
|
||||
await provider.handleModeSwitch(this.pausedModeSlug)
|
||||
|
||||
// Delay to allow mode change to take effect
|
||||
await delay(500)
|
||||
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} successfully restored to '${this.pausedModeSlug}' mode from history`,
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
provider.log(
|
||||
`[subtasks] task ${this.taskId}.${this.instanceId} failed to restore mode to '${this.pausedModeSlug}' from history: ${error}`,
|
||||
)
|
||||
// Continue execution even if mode restoration fails
|
||||
}
|
||||
}
|
||||
|
||||
// since we don't use api_req_finished anymore, we need to check if the last api_req_started has a cost value, if it doesn't and no cancellation reason to present, then we remove it since it indicates an api request without any partial content streamed
|
||||
const lastApiReqStartedIndex = findLastIndex(
|
||||
modifiedClineMessages,
|
||||
|
|
@ -1451,6 +1509,35 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
|
||||
await abortStream(cancelReason, streamingFailedMessage)
|
||||
|
||||
// Enhanced error handling for sub-tasks: ensure parent task mode is restored
|
||||
// when a sub-task is interrupted
|
||||
if (this.parentTask && provider) {
|
||||
try {
|
||||
const parentPausedMode = this.parentTask.pausedModeSlug
|
||||
if (parentPausedMode && parentPausedMode !== defaultModeSlug) {
|
||||
const currentState = await provider.getState()
|
||||
const currentMode = currentState?.mode ?? defaultModeSlug
|
||||
|
||||
if (currentMode !== parentPausedMode) {
|
||||
provider.log(
|
||||
`[subtasks] sub-task ${this.taskId}.${this.instanceId} interrupted - restoring parent mode from '${currentMode}' to '${parentPausedMode}'`,
|
||||
)
|
||||
|
||||
await provider.handleModeSwitch(parentPausedMode)
|
||||
|
||||
provider.log(
|
||||
`[subtasks] successfully restored parent mode to '${parentPausedMode}' after sub-task interruption`,
|
||||
)
|
||||
}
|
||||
}
|
||||
} catch (modeError) {
|
||||
provider.log(
|
||||
`[subtasks] failed to restore parent mode after sub-task interruption: ${modeError}`,
|
||||
)
|
||||
// Continue execution even if mode restoration fails
|
||||
}
|
||||
}
|
||||
|
||||
const history = await provider?.getTaskWithId(this.taskId)
|
||||
|
||||
if (history) {
|
||||
|
|
|
|||
|
|
@ -228,8 +228,38 @@ export class ClineProvider
|
|||
// this is used when a sub task is finished and the parent task needs to be resumed
|
||||
async finishSubTask(lastMessage: string) {
|
||||
console.log(`[subtasks] finishing subtask ${lastMessage}`)
|
||||
|
||||
// Get the parent task before removing the current one
|
||||
const parentTask = this.clineStack.length > 1 ? this.clineStack[this.clineStack.length - 2] : undefined
|
||||
|
||||
// remove the last cline instance from the stack (this is the finished sub task)
|
||||
await this.removeClineFromStack()
|
||||
|
||||
// Additional safety net: ensure mode is restored for the parent task
|
||||
if (parentTask && parentTask.pausedModeSlug) {
|
||||
try {
|
||||
const currentState = await this.getState()
|
||||
const currentMode = currentState?.mode ?? defaultModeSlug
|
||||
|
||||
if (currentMode !== parentTask.pausedModeSlug) {
|
||||
this.log(
|
||||
`[subtasks] finishSubTask: restoring mode from '${currentMode}' to '${parentTask.pausedModeSlug}' for parent task ${parentTask.taskId}`,
|
||||
)
|
||||
|
||||
await this.handleModeSwitch(parentTask.pausedModeSlug)
|
||||
|
||||
this.log(
|
||||
`[subtasks] finishSubTask: successfully restored mode to '${parentTask.pausedModeSlug}' for parent task ${parentTask.taskId}`,
|
||||
)
|
||||
}
|
||||
} catch (error) {
|
||||
this.log(
|
||||
`[subtasks] finishSubTask: failed to restore mode to '${parentTask.pausedModeSlug}' for parent task ${parentTask.taskId}: ${error}`,
|
||||
)
|
||||
// Continue execution even if mode restoration fails
|
||||
}
|
||||
}
|
||||
|
||||
// resume the last cline instance in the stack (if it exists - this is the 'parent' calling task)
|
||||
await this.getCurrentCline()?.resumePausedTask(lastMessage)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue