mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
refactor: centralize abort/streaming state reset logic and use safe JSON parsing
- Extract duplicated abort/streaming state reset logic into private helper method resetAbortAndStreamingState() - Update resumeTaskFromHistory() and presentResumableAsk() to use the helper method - Replace unsafe JSON.parse() with safeJsonParse() in ClineProvider.ts for better error handling Addresses review feedback from @mrubens on PR #8986
This commit is contained in:
parent
ac57bd0209
commit
58cbc690e4
2 changed files with 35 additions and 38 deletions
|
|
@ -1353,24 +1353,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
// (abandoned = false), we keep the instance alive but set abort = true.
|
||||
// We only clear these flags after the user confirms they want to resume,
|
||||
// preventing the old stream from continuing if abort was set.
|
||||
this.abort = false
|
||||
this.abandoned = false
|
||||
this.abortReason = undefined
|
||||
this.didFinishAbortingStream = false
|
||||
this.isStreaming = false
|
||||
|
||||
// Reset streaming-local fields to avoid stale state from previous stream
|
||||
this.currentStreamingContentIndex = 0
|
||||
this.currentStreamingDidCheckpoint = false
|
||||
this.assistantMessageContent = []
|
||||
this.didCompleteReadingStream = false
|
||||
this.userMessageContent = []
|
||||
this.userMessageContentReady = false
|
||||
this.didRejectTool = false
|
||||
this.didAlreadyUseTool = false
|
||||
this.presentAssistantMessageLocked = false
|
||||
this.presentAssistantMessageHasPendingUpdates = false
|
||||
this.assistantMessageParser.reset()
|
||||
this.resetAbortAndStreamingState()
|
||||
|
||||
let responseText: string | undefined
|
||||
let responseImages: string[] | undefined
|
||||
|
|
@ -1550,6 +1533,33 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
await this.initiateTaskLoop(newUserContent)
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets abort flags and streaming state to allow task resumption.
|
||||
* Centralizes the state reset logic used after user confirms task resumption.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private resetAbortAndStreamingState(): void {
|
||||
this.abort = false
|
||||
this.abandoned = false
|
||||
this.abortReason = undefined
|
||||
this.didFinishAbortingStream = false
|
||||
this.isStreaming = false
|
||||
|
||||
// Reset streaming-local fields to avoid stale state from previous stream
|
||||
this.currentStreamingContentIndex = 0
|
||||
this.currentStreamingDidCheckpoint = false
|
||||
this.assistantMessageContent = []
|
||||
this.didCompleteReadingStream = false
|
||||
this.userMessageContent = []
|
||||
this.userMessageContentReady = false
|
||||
this.didRejectTool = false
|
||||
this.didAlreadyUseTool = false
|
||||
this.presentAssistantMessageLocked = false
|
||||
this.presentAssistantMessageHasPendingUpdates = false
|
||||
this.assistantMessageParser.reset()
|
||||
}
|
||||
|
||||
/**
|
||||
* Present a resumable ask on an aborted task without rehydrating.
|
||||
* Used by soft-interrupt (cancelTask) to show Resume/Terminate UI.
|
||||
|
|
@ -1574,24 +1584,7 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
// If user clicked Resume (not Terminate), reset abort flags and continue
|
||||
if (response === "yesButtonClicked" || response === "messageResponse") {
|
||||
// Reset abort flags to allow the loop to continue
|
||||
this.abort = false
|
||||
this.abandoned = false
|
||||
this.abortReason = undefined
|
||||
this.didFinishAbortingStream = false
|
||||
this.isStreaming = false
|
||||
|
||||
// Reset streaming-local fields to avoid stale state from previous stream
|
||||
this.currentStreamingContentIndex = 0
|
||||
this.currentStreamingDidCheckpoint = false
|
||||
this.assistantMessageContent = []
|
||||
this.didCompleteReadingStream = false
|
||||
this.userMessageContent = []
|
||||
this.userMessageContentReady = false
|
||||
this.didRejectTool = false
|
||||
this.didAlreadyUseTool = false
|
||||
this.presentAssistantMessageLocked = false
|
||||
this.presentAssistantMessageHasPendingUpdates = false
|
||||
this.assistantMessageParser.reset()
|
||||
this.resetAbortAndStreamingState()
|
||||
|
||||
// Prepare content for resuming the task loop
|
||||
let userContent: Anthropic.Messages.ContentBlockParam[] = []
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ import { Package } from "../../shared/package"
|
|||
import { findLast } from "../../shared/array"
|
||||
import { supportPrompt } from "../../shared/support-prompt"
|
||||
import { GlobalFileNames } from "../../shared/globalFileNames"
|
||||
import { safeJsonParse } from "../../shared/safeJsonParse"
|
||||
import type { ExtensionMessage, ExtensionState, MarketplaceInstalledMetadata } from "../../shared/ExtensionMessage"
|
||||
import { Mode, defaultModeSlug, getModeBySlug } from "../../shared/modes"
|
||||
import { experimentDefault } from "../../shared/experiments"
|
||||
|
|
@ -2665,9 +2666,12 @@ export class ClineProvider
|
|||
|
||||
if (lastApiReqStartedIndex !== -1) {
|
||||
const lastApiReqStarted = task.clineMessages[lastApiReqStartedIndex]
|
||||
const apiReqInfo = JSON.parse(lastApiReqStarted.text || "{}")
|
||||
const apiReqInfo = safeJsonParse<{ cost?: number; cancelReason?: string }>(
|
||||
lastApiReqStarted.text || "{}",
|
||||
{},
|
||||
)
|
||||
|
||||
if (apiReqInfo.cost === undefined && apiReqInfo.cancelReason === undefined) {
|
||||
if (apiReqInfo && apiReqInfo.cost === undefined && apiReqInfo.cancelReason === undefined) {
|
||||
apiReqInfo.cancelReason = "user_cancelled"
|
||||
lastApiReqStarted.text = JSON.stringify(apiReqInfo)
|
||||
await task.overwriteClineMessages([...task.clineMessages])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue