mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix: preserve conversation state when cancelling reasoning model mid-thinking
- Modified ClineProvider.cancelTask() to preserve current conversation state instead of reverting to saved history - Enhanced abortStream() to properly handle partial reasoning messages during cancellation - Ensures frontend displays correct current conversation rather than previous conversation from disk - Fixes issue #5810 where cancelling reasoning models caused conversation replacement The fix works by: 1. Capturing current clineMessages and apiConversationHistory before cancellation 2. Creating new task instance with preserved state instead of loading from saved history 3. Properly handling partial reasoning messages during stream abortion 4. Maintaining conversation integrity throughout the cancellation process
This commit is contained in:
parent
6cf376f832
commit
32d70c7541
3 changed files with 7664 additions and 3 deletions
7625
package-lock.json
generated
Normal file
7625
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -1306,7 +1306,14 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
lastMessage.partial = false
|
||||
// instead of streaming partialMessage events, we do a save and post like normal to persist to disk
|
||||
console.log("updating partial message", lastMessage)
|
||||
// await this.saveClineMessages()
|
||||
|
||||
// For reasoning messages, preserve the current content
|
||||
if (lastMessage.say === "reasoning" && reasoningMessage) {
|
||||
lastMessage.text = reasoningMessage
|
||||
}
|
||||
|
||||
// Save the updated partial message to preserve current state
|
||||
await this.saveClineMessages()
|
||||
}
|
||||
|
||||
// Let assistant know their response was interrupted for when task is resumed
|
||||
|
|
|
|||
|
|
@ -969,6 +969,10 @@ export class ClineProvider
|
|||
|
||||
console.log(`[subtasks] cancelling task ${cline.taskId}.${cline.instanceId}`)
|
||||
|
||||
// Preserve current conversation state before cancellation
|
||||
const currentClineMessages = [...cline.clineMessages]
|
||||
const currentApiHistory = [...cline.apiConversationHistory]
|
||||
|
||||
const { historyItem } = await this.getTaskWithId(cline.taskId)
|
||||
// Preserve parent and root task information for history item.
|
||||
const rootTask = cline.rootTask
|
||||
|
|
@ -999,8 +1003,33 @@ export class ClineProvider
|
|||
this.getCurrentCline()!.abandoned = true
|
||||
}
|
||||
|
||||
// Clears task again, so we need to abortTask manually above.
|
||||
await this.initClineWithHistoryItem({ ...historyItem, rootTask, parentTask })
|
||||
// Create new task with preserved conversation state instead of reverting to saved history
|
||||
const newCline = new Task({
|
||||
provider: this,
|
||||
apiConfiguration: cline.apiConfiguration,
|
||||
enableDiff: cline.diffEnabled,
|
||||
enableCheckpoints: cline.enableCheckpoints,
|
||||
fuzzyMatchThreshold: cline.fuzzyMatchThreshold,
|
||||
consecutiveMistakeLimit: cline.consecutiveMistakeLimit,
|
||||
historyItem: historyItem,
|
||||
experiments: (await this.getState()).experiments,
|
||||
startTask: false,
|
||||
rootTask,
|
||||
parentTask,
|
||||
taskNumber: cline.taskNumber,
|
||||
onCreated: (cline) => this.emit("clineCreated", cline),
|
||||
})
|
||||
|
||||
// Restore the current conversation state instead of loading from disk
|
||||
await newCline.overwriteClineMessages(currentClineMessages)
|
||||
await newCline.overwriteApiConversationHistory(currentApiHistory)
|
||||
|
||||
// Mark as initialized and add to stack
|
||||
newCline.isInitialized = true
|
||||
await this.addClineToStack(newCline)
|
||||
|
||||
// Update webview with current state
|
||||
await this.postStateToWebview()
|
||||
}
|
||||
|
||||
async updateCustomInstructions(instructions?: string) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue