Skip to content

Commit 227c719

Browse files
move saveClineMessagesAndUpdateHistory out to a separate state utilities file (RooCodeInc#4190)
1 parent 5e55a7a commit 227c719

File tree

2 files changed

+238
-64
lines changed

2 files changed

+238
-64
lines changed

src/core/task/index.ts

Lines changed: 172 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import { processFilesIntoText } from "@integrations/misc/extract-text"
114114
import { featureFlagsService } from "@services/posthog/feature-flags/FeatureFlagsService"
115115
import { StreamingJsonReplacer, ChangeLocation } from "@core/assistant-message/diff-json"
116116
import { isClaude4ModelFamily } from "@/utils/model-utils"
117+
import { saveClineMessagesAndUpdateHistory } from "./message-state"
117118

118119
export const USE_EXPERIMENTAL_CLAUDE4_FEATURES = false
119120

@@ -343,52 +344,28 @@ export class Task {
343344
message.conversationHistoryIndex = this.apiConversationHistory.length - 1 // NOTE: this is the index of the last added message which is the user message, and once the clinemessages have been presented we update the apiconversationhistory with the completed assistant message. This means when resetting to a message, we need to +1 this index to get the correct assistant message that this tool use corresponds to
344345
message.conversationHistoryDeletedRange = this.conversationHistoryDeletedRange
345346
this.clineMessages.push(message)
346-
await this.saveClineMessagesAndUpdateHistory()
347+
await saveClineMessagesAndUpdateHistory(
348+
this.getContext(),
349+
this.taskId,
350+
this.clineMessages,
351+
this.taskIsFavorited ?? false,
352+
this.conversationHistoryDeletedRange,
353+
this.checkpointTracker,
354+
this.updateTaskHistory,
355+
)
347356
}
348357

349358
private async overwriteClineMessages(newMessages: ClineMessage[]) {
350359
this.clineMessages = newMessages
351-
await this.saveClineMessagesAndUpdateHistory()
352-
}
353-
354-
private async saveClineMessagesAndUpdateHistory() {
355-
try {
356-
await saveClineMessages(this.getContext(), this.taskId, this.clineMessages)
357-
358-
// combined as they are in ChatView
359-
const apiMetrics = getApiMetrics(combineApiRequests(combineCommandSequences(this.clineMessages.slice(1))))
360-
const taskMessage = this.clineMessages[0] // first message is always the task say
361-
const lastRelevantMessage =
362-
this.clineMessages[
363-
findLastIndex(this.clineMessages, (m) => !(m.ask === "resume_task" || m.ask === "resume_completed_task"))
364-
]
365-
const taskDir = await ensureTaskDirectoryExists(this.getContext(), this.taskId)
366-
let taskDirSize = 0
367-
try {
368-
// getFolderSize.loose silently ignores errors
369-
// returns # of bytes, size/1000/1000 = MB
370-
taskDirSize = await getFolderSize.loose(taskDir)
371-
} catch (error) {
372-
console.error("Failed to get task directory size:", taskDir, error)
373-
}
374-
await this.updateTaskHistory({
375-
id: this.taskId,
376-
ts: lastRelevantMessage.ts,
377-
task: taskMessage.text ?? "",
378-
tokensIn: apiMetrics.totalTokensIn,
379-
tokensOut: apiMetrics.totalTokensOut,
380-
cacheWrites: apiMetrics.totalCacheWrites,
381-
cacheReads: apiMetrics.totalCacheReads,
382-
totalCost: apiMetrics.totalCost,
383-
size: taskDirSize,
384-
shadowGitConfigWorkTree: await this.checkpointTracker?.getShadowGitConfigWorkTree(),
385-
cwdOnTaskInitialization: cwd,
386-
conversationHistoryDeletedRange: this.conversationHistoryDeletedRange,
387-
isFavorited: this.taskIsFavorited,
388-
})
389-
} catch (error) {
390-
console.error("Failed to save cline messages:", error)
391-
}
360+
await saveClineMessagesAndUpdateHistory(
361+
this.getContext(),
362+
this.taskId,
363+
this.clineMessages,
364+
this.taskIsFavorited ?? false,
365+
this.conversationHistoryDeletedRange,
366+
this.checkpointTracker,
367+
this.updateTaskHistory,
368+
)
392369
}
393370

394371
async restoreCheckpoint(messageTs: number, restoreType: ClineCheckpointRestore, offset?: number) {
@@ -515,9 +492,15 @@ export class Task {
515492
})
516493
}
517494

518-
await this.saveClineMessagesAndUpdateHistory()
519-
520-
sendRelinquishControlEvent()
495+
await saveClineMessagesAndUpdateHistory(
496+
this.getContext(),
497+
this.taskId,
498+
this.clineMessages,
499+
this.taskIsFavorited ?? false,
500+
this.conversationHistoryDeletedRange,
501+
this.checkpointTracker,
502+
this.updateTaskHistory,
503+
)
521504

522505
this.cancelTask() // the task is already cancelled by the provider beforehand, but we need to re-init to get the updated messages
523506
} else {
@@ -790,7 +773,15 @@ export class Task {
790773
// lastMessage.ts = askTs
791774
lastMessage.text = text
792775
lastMessage.partial = false
793-
await this.saveClineMessagesAndUpdateHistory()
776+
await saveClineMessagesAndUpdateHistory(
777+
this.getContext(),
778+
this.taskId,
779+
this.clineMessages,
780+
this.taskIsFavorited ?? false,
781+
this.conversationHistoryDeletedRange,
782+
this.checkpointTracker,
783+
this.updateTaskHistory,
784+
)
794785
// await this.postStateToWebview()
795786
const protoMessage = convertClineMessageToProto(lastMessage)
796787
await sendPartialMessageEvent(protoMessage)
@@ -898,7 +889,15 @@ export class Task {
898889
lastMessage.partial = false
899890

900891
// instead of streaming partialMessage events, we do a save and post like normal to persist to disk
901-
await this.saveClineMessagesAndUpdateHistory()
892+
await saveClineMessagesAndUpdateHistory(
893+
this.getContext(),
894+
this.taskId,
895+
this.clineMessages,
896+
this.taskIsFavorited ?? false,
897+
this.conversationHistoryDeletedRange,
898+
this.checkpointTracker,
899+
this.updateTaskHistory,
900+
)
902901
// await this.postStateToWebview()
903902
const protoMessage = convertClineMessageToProto(lastMessage)
904903
await sendPartialMessageEvent(protoMessage) // more performant than an entire postStateToWebview
@@ -947,8 +946,15 @@ export class Task {
947946
const lastMessage = this.clineMessages.at(-1)
948947
if (lastMessage?.partial && lastMessage.type === type && (lastMessage.ask === askOrSay || lastMessage.say === askOrSay)) {
949948
this.clineMessages.pop()
950-
await this.saveClineMessagesAndUpdateHistory()
951-
await this.postStateToWebview()
949+
await saveClineMessagesAndUpdateHistory(
950+
this.getContext(),
951+
this.taskId,
952+
this.clineMessages,
953+
this.taskIsFavorited ?? false,
954+
this.conversationHistoryDeletedRange,
955+
this.checkpointTracker,
956+
this.updateTaskHistory,
957+
)
952958
}
953959
}
954960

@@ -1232,7 +1238,15 @@ export class Task {
12321238
const lastCheckpointMessage = findLast(this.clineMessages, (m) => m.say === "checkpoint_created")
12331239
if (lastCheckpointMessage) {
12341240
lastCheckpointMessage.lastCheckpointHash = commitHash
1235-
await this.saveClineMessagesAndUpdateHistory()
1241+
await saveClineMessagesAndUpdateHistory(
1242+
this.getContext(),
1243+
this.taskId,
1244+
this.clineMessages,
1245+
this.taskIsFavorited ?? false,
1246+
this.conversationHistoryDeletedRange,
1247+
this.checkpointTracker,
1248+
this.updateTaskHistory,
1249+
)
12361250
}
12371251
}) // silently fails for now
12381252

@@ -1264,7 +1278,15 @@ export class Task {
12641278
)
12651279
if (lastCompletionResultMessage) {
12661280
lastCompletionResultMessage.lastCheckpointHash = commitHash
1267-
await this.saveClineMessagesAndUpdateHistory()
1281+
await saveClineMessagesAndUpdateHistory(
1282+
this.getContext(),
1283+
this.taskId,
1284+
this.clineMessages,
1285+
this.taskIsFavorited ?? false,
1286+
this.conversationHistoryDeletedRange,
1287+
this.checkpointTracker,
1288+
this.updateTaskHistory,
1289+
)
12681290
}
12691291
} else {
12701292
console.error("Checkpoint tracker does not exist and could not be initialized for attempt completion")
@@ -1702,7 +1724,15 @@ export class Task {
17021724

17031725
if (contextManagementMetadata.updatedConversationHistoryDeletedRange) {
17041726
this.conversationHistoryDeletedRange = contextManagementMetadata.conversationHistoryDeletedRange
1705-
await this.saveClineMessagesAndUpdateHistory() // saves task history item which we use to keep track of conversation history deleted range
1727+
await saveClineMessagesAndUpdateHistory(
1728+
this.getContext(),
1729+
this.taskId,
1730+
this.clineMessages,
1731+
this.taskIsFavorited ?? false,
1732+
this.conversationHistoryDeletedRange,
1733+
this.checkpointTracker,
1734+
this.updateTaskHistory,
1735+
) // saves task history item which we use to keep track of conversation history deleted range
17061736
}
17071737

17081738
let stream = this.api.createMessage(systemPrompt, contextManagementMetadata.truncatedConversationHistory)
@@ -1727,7 +1757,15 @@ export class Task {
17271757
this.conversationHistoryDeletedRange,
17281758
"quarter", // Force aggressive truncation
17291759
)
1730-
await this.saveClineMessagesAndUpdateHistory()
1760+
await saveClineMessagesAndUpdateHistory(
1761+
this.getContext(),
1762+
this.taskId,
1763+
this.clineMessages,
1764+
this.taskIsFavorited ?? false,
1765+
this.conversationHistoryDeletedRange,
1766+
this.checkpointTracker,
1767+
this.updateTaskHistory,
1768+
)
17311769
await this.contextManager.triggerApplyStandardContextTruncationNoticeChange(
17321770
Date.now(),
17331771
await ensureTaskDirectoryExists(this.getContext(), this.taskId),
@@ -1741,7 +1779,15 @@ export class Task {
17411779
this.conversationHistoryDeletedRange,
17421780
"quarter", // Force aggressive truncation
17431781
)
1744-
await this.saveClineMessagesAndUpdateHistory()
1782+
await saveClineMessagesAndUpdateHistory(
1783+
this.getContext(),
1784+
this.taskId,
1785+
this.clineMessages,
1786+
this.taskIsFavorited ?? false,
1787+
this.conversationHistoryDeletedRange,
1788+
this.checkpointTracker,
1789+
this.updateTaskHistory,
1790+
)
17451791
await this.contextManager.triggerApplyStandardContextTruncationNoticeChange(
17461792
Date.now(),
17471793
await ensureTaskDirectoryExists(this.getContext(), this.taskId),
@@ -3505,8 +3551,15 @@ export class Task {
35053551
...sharedMessage,
35063552
selected: text,
35073553
} satisfies ClineAskQuestion)
3508-
await this.saveClineMessagesAndUpdateHistory()
3509-
telemetryService.captureOptionSelected(this.taskId, options.length, "act")
3554+
await saveClineMessagesAndUpdateHistory(
3555+
this.getContext(),
3556+
this.taskId,
3557+
this.clineMessages,
3558+
this.taskIsFavorited ?? false,
3559+
this.conversationHistoryDeletedRange,
3560+
this.checkpointTracker,
3561+
this.updateTaskHistory,
3562+
)
35103563
}
35113564
} else {
35123565
// Option not selected, send user feedback
@@ -3638,7 +3691,15 @@ export class Task {
36383691
this.conversationHistoryDeletedRange,
36393692
keepStrategy,
36403693
)
3641-
await this.saveClineMessagesAndUpdateHistory()
3694+
await saveClineMessagesAndUpdateHistory(
3695+
this.getContext(),
3696+
this.taskId,
3697+
this.clineMessages,
3698+
this.taskIsFavorited ?? false,
3699+
this.conversationHistoryDeletedRange,
3700+
this.checkpointTracker,
3701+
this.updateTaskHistory,
3702+
)
36423703
await this.contextManager.triggerApplyStandardContextTruncationNoticeChange(
36433704
Date.now(),
36443705
await ensureTaskDirectoryExists(this.getContext(), this.taskId),
@@ -3939,8 +4000,15 @@ export class Task {
39394000
...sharedMessage,
39404001
selected: text,
39414002
} satisfies ClinePlanModeResponse)
3942-
await this.saveClineMessagesAndUpdateHistory()
3943-
telemetryService.captureOptionSelected(this.taskId, options.length, "plan")
4003+
await saveClineMessagesAndUpdateHistory(
4004+
this.getContext(),
4005+
this.taskId,
4006+
this.clineMessages,
4007+
this.taskIsFavorited ?? false,
4008+
this.conversationHistoryDeletedRange,
4009+
this.checkpointTracker,
4010+
this.updateTaskHistory,
4011+
)
39444012
}
39454013
} else {
39464014
// Option not selected, send user feedback
@@ -4042,7 +4110,15 @@ export class Task {
40424110
) {
40434111
lastCompletionResultMessage.text += COMPLETION_RESULT_CHANGES_FLAG
40444112
}
4045-
await this.saveClineMessagesAndUpdateHistory()
4113+
await saveClineMessagesAndUpdateHistory(
4114+
this.getContext(),
4115+
this.taskId,
4116+
this.clineMessages,
4117+
this.taskIsFavorited ?? false,
4118+
this.conversationHistoryDeletedRange,
4119+
this.checkpointTracker,
4120+
this.updateTaskHistory,
4121+
)
40464122
}
40474123

40484124
try {
@@ -4377,7 +4453,15 @@ export class Task {
43774453
this.clineMessages[lastApiReqIndex].text = JSON.stringify({
43784454
request: userContent.map((block) => formatContentBlockToMarkdown(block)).join("\n\n"),
43794455
} satisfies ClineApiReqInfo)
4380-
await this.saveClineMessagesAndUpdateHistory()
4456+
await saveClineMessagesAndUpdateHistory(
4457+
this.getContext(),
4458+
this.taskId,
4459+
this.clineMessages,
4460+
this.taskIsFavorited ?? false,
4461+
this.conversationHistoryDeletedRange,
4462+
this.checkpointTracker,
4463+
this.updateTaskHistory,
4464+
)
43814465
await this.postStateToWebview()
43824466

43834467
try {
@@ -4448,7 +4532,15 @@ export class Task {
44484532

44494533
// update api_req_started to have cancelled and cost, so that we can display the cost of the partial stream
44504534
updateApiReqMsg(cancelReason, streamingFailedMessage)
4451-
await this.saveClineMessagesAndUpdateHistory()
4535+
await saveClineMessagesAndUpdateHistory(
4536+
this.getContext(),
4537+
this.taskId,
4538+
this.clineMessages,
4539+
this.taskIsFavorited ?? false,
4540+
this.conversationHistoryDeletedRange,
4541+
this.checkpointTracker,
4542+
this.updateTaskHistory,
4543+
)
44524544

44534545
telemetryService.captureConversationTurnEvent(
44544546
this.taskId,
@@ -4574,7 +4666,15 @@ export class Task {
45744666
totalCost = apiStreamUsage.totalCost
45754667
}
45764668
updateApiReqMsg()
4577-
await this.saveClineMessagesAndUpdateHistory()
4669+
await saveClineMessagesAndUpdateHistory(
4670+
this.getContext(),
4671+
this.taskId,
4672+
this.clineMessages,
4673+
this.taskIsFavorited ?? false,
4674+
this.conversationHistoryDeletedRange,
4675+
this.checkpointTracker,
4676+
this.updateTaskHistory,
4677+
)
45784678
await this.postStateToWebview()
45794679
})
45804680
}
@@ -4598,7 +4698,15 @@ export class Task {
45984698
}
45994699

46004700
updateApiReqMsg()
4601-
await this.saveClineMessagesAndUpdateHistory()
4701+
await saveClineMessagesAndUpdateHistory(
4702+
this.getContext(),
4703+
this.taskId,
4704+
this.clineMessages,
4705+
this.taskIsFavorited ?? false,
4706+
this.conversationHistoryDeletedRange,
4707+
this.checkpointTracker,
4708+
this.updateTaskHistory,
4709+
)
46024710
await this.postStateToWebview()
46034711

46044712
// now add to apiconversationhistory

0 commit comments

Comments
 (0)