Skip to content

Commit 58825a2

Browse files
author
Eric Wheeler
committed
refactor: make condenseContext history updates atomic
Moves the conversation summarization logic into the critical section of `modifyApiConversationHistory`. This refactoring ensures that the process of reading the existing history, summarizing it, and writing the condensed version back to disk is a single, atomic transaction. Previously, the summary was generated outside the critical section, creating a potential race condition where the history could have changed between summarization and writing. Additionally, any side effects, such as `say()` notifications, are now performed only after the atomic write operation has successfully completed, preventing deadlocks and ensuring a cleaner separation of concerns. Signed-off-by: Eric Wheeler <[email protected]>
1 parent 8ad5443 commit 58825a2

File tree

1 file changed

+32
-23
lines changed

1 file changed

+32
-23
lines changed

src/core/task/Task.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -672,26 +672,40 @@ export class Task extends EventEmitter<ClineEvents> {
672672
}
673673

674674
const { contextTokens: prevContextTokens } = this.getTokenUsage()
675-
const {
676-
messages,
677-
summary,
678-
cost,
679-
newContextTokens = 0,
680-
error,
681-
} = await summarizeConversation(
682-
this.apiConversationHistory,
683-
this.api, // Main API handler (fallback)
684-
systemPrompt, // Default summarization prompt (fallback)
685-
this.taskId,
686-
prevContextTokens,
687-
false, // manual trigger
688-
customCondensingPrompt, // User's custom prompt
689-
condensingApiHandler, // Specific handler for condensing
690-
)
691-
if (error) {
675+
676+
let contextCondense: ContextCondense | undefined
677+
let errorResult: string | undefined = undefined
678+
679+
await this.modifyApiConversationHistory(async (history) => {
680+
const {
681+
messages,
682+
summary,
683+
cost,
684+
newContextTokens = 0,
685+
error,
686+
} = await summarizeConversation(
687+
history,
688+
this.api, // Main API handler (fallback)
689+
systemPrompt, // Default summarization prompt (fallback)
690+
this.taskId,
691+
prevContextTokens,
692+
false, // manual trigger
693+
customCondensingPrompt, // User's custom prompt
694+
condensingApiHandler, // Specific handler for condensing
695+
)
696+
if (error) {
697+
errorResult = error
698+
return undefined // abort transaction
699+
}
700+
701+
contextCondense = { summary, cost, newContextTokens, prevContextTokens }
702+
return messages
703+
})
704+
705+
if (errorResult) {
692706
this.say(
693707
"condense_context_error",
694-
error,
708+
errorResult,
695709
undefined /* images */,
696710
false /* partial */,
697711
undefined /* checkpoint */,
@@ -701,11 +715,6 @@ export class Task extends EventEmitter<ClineEvents> {
701715
return
702716
}
703717

704-
await this.modifyApiConversationHistory(async () => {
705-
return messages
706-
})
707-
708-
const contextCondense: ContextCondense = { summary, cost, newContextTokens, prevContextTokens }
709718
await this.say(
710719
"condense_context",
711720
undefined /* text */,

0 commit comments

Comments
 (0)