mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: prevent conversation history loss when canceling during response
- Add explicit saveApiConversationHistory() call after adding interrupted message in abortStream - Reverse order of abortStream/abortTask calls to save state before cleanup - Add safety check in saveApiMessages to prevent overwriting non-empty history with empty array Fixes #8153
This commit is contained in:
parent
87b45def18
commit
41789177d3
2 changed files with 32 additions and 2 deletions
|
|
@ -79,5 +79,31 @@ export async function saveApiMessages({
|
|||
}) {
|
||||
const taskDir = await getTaskDirectoryPath(globalStoragePath, taskId)
|
||||
const filePath = path.join(taskDir, GlobalFileNames.apiConversationHistory)
|
||||
|
||||
// Safety check: prevent saving an empty array if a non-empty conversation previously existed
|
||||
if (Array.isArray(messages) && messages.length === 0) {
|
||||
// Check if there's an existing non-empty conversation history
|
||||
if (await fileExistsAtPath(filePath)) {
|
||||
try {
|
||||
const existingContent = await fs.readFile(filePath, "utf8")
|
||||
const existingData = JSON.parse(existingContent)
|
||||
if (Array.isArray(existingData) && existingData.length > 0) {
|
||||
console.error(
|
||||
`[Roo-Debug] saveApiMessages: Attempted to save empty array over existing non-empty conversation. ` +
|
||||
`TaskId: ${taskId}, Existing messages count: ${existingData.length}. ` +
|
||||
`Skipping save to prevent data loss.`,
|
||||
)
|
||||
return // Don't save empty array over non-empty conversation
|
||||
}
|
||||
} catch (error) {
|
||||
// If we can't read/parse the existing file, proceed with save
|
||||
console.error(
|
||||
`[Roo-Debug] saveApiMessages: Error checking existing conversation history. ` +
|
||||
`TaskId: ${taskId}, Error: ${error}. Proceeding with save.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await safeWriteJson(filePath, messages)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1904,6 +1904,9 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
],
|
||||
})
|
||||
|
||||
// Explicitly save the API conversation history after adding the interrupted message
|
||||
await this.saveApiConversationHistory()
|
||||
|
||||
// Update `api_req_started` to have cancelled and cost, so that
|
||||
// we can display the cost of the partial stream.
|
||||
updateApiReqMsg(cancelReason, streamingFailedMessage)
|
||||
|
|
@ -2196,9 +2199,10 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
? undefined
|
||||
: (error.message ?? JSON.stringify(serializeError(error), null, 2))
|
||||
|
||||
// Now call abortTask after determining the cancel reason.
|
||||
await this.abortTask()
|
||||
// Reverse the order: call abortStream first to properly save the interrupted message
|
||||
// before abortTask cleans up resources
|
||||
await abortStream(cancelReason, streamingFailedMessage)
|
||||
await this.abortTask()
|
||||
|
||||
const history = await provider?.getTaskWithId(this.taskId)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue