Skip to content

Commit b6005bf

Browse files
committed
fix: resume parent task when subtask gets interrupted
- Add handleInterruptedSubtask method to properly handle interrupted subtasks - Check and unpause parent tasks in resumeTaskFromHistory when they were waiting for an interrupted subtask - Add proper logging and conversation history updates when subtask is interrupted Fixes #7780
1 parent 2571781 commit b6005bf

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

src/core/task/Task.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,6 +1228,12 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
12281228
}
12291229
}
12301230

1231+
// Check if this task was paused waiting for a subtask that got interrupted
1232+
// If so, handle the interrupted subtask properly
1233+
if (this.isPaused && this.childTaskId) {
1234+
await this.handleInterruptedSubtask()
1235+
}
1236+
12311237
const modifiedClineMessages = await this.getSavedClineMessages()
12321238

12331239
// Check for any stored GPT-5 response IDs in the message history.
@@ -1657,6 +1663,55 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
16571663
}
16581664
}
16591665

1666+
/**
1667+
* Handle the case when a subtask was interrupted (e.g., due to 5-hour limit)
1668+
* and the parent task needs to be resumed without the subtask result.
1669+
*/
1670+
public async handleInterruptedSubtask() {
1671+
if (!this.isPaused || !this.childTaskId) {
1672+
return // Not waiting for a subtask
1673+
}
1674+
1675+
const provider = this.providerRef.deref()
1676+
provider?.log(
1677+
`[handleInterruptedSubtask] Handling interrupted subtask ${this.childTaskId} for parent task ${this.taskId}`,
1678+
)
1679+
1680+
// Clear the paused state
1681+
this.isPaused = false
1682+
const interruptedChildId = this.childTaskId
1683+
this.childTaskId = undefined
1684+
1685+
// Clear any pause interval
1686+
if (this.pauseInterval) {
1687+
clearInterval(this.pauseInterval)
1688+
this.pauseInterval = undefined
1689+
}
1690+
1691+
// Emit event to update UI
1692+
this.emit(RooCodeEventName.TaskUnpaused, this.taskId)
1693+
1694+
// Add a message to the conversation history indicating the subtask was interrupted
1695+
try {
1696+
await this.say("subtask_result", `[Subtask ${interruptedChildId} was interrupted and could not complete]`)
1697+
1698+
await this.addToApiConversationHistory({
1699+
role: "user",
1700+
content: [
1701+
{
1702+
type: "text",
1703+
text: `[new_task interrupted] The subtask was interrupted before completion. Please continue with the main task.`,
1704+
},
1705+
],
1706+
})
1707+
1708+
// Set skipPrevResponseIdOnce to ensure continuity
1709+
this.skipPrevResponseIdOnce = true
1710+
} catch (error) {
1711+
provider?.log(`Error handling interrupted subtask: ${error}`)
1712+
}
1713+
}
1714+
16601715
// Task Loop
16611716

16621717
private async initiateTaskLoop(userContent: Anthropic.Messages.ContentBlockParam[]): Promise<void> {

0 commit comments

Comments
 (0)