Revert "Remove the ask promise error" (#2117)

Revert "Remove the ask promise error (#2107)"

This reverts commit 712ca71ee0.
This commit is contained in:
Matt Rubens 2025-03-30 13:33:04 -04:00 committed by GitHub
parent 592494fb29
commit a7d31aa9ba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 29 additions and 23 deletions

View file

@ -142,6 +142,7 @@ export class Cline extends EventEmitter<ClineEvents> {
private askResponse?: ClineAskResponse
private askResponseText?: string
private askResponseImages?: string[]
private lastMessageTs?: number
// Not private since it needs to be accessible by tools
consecutiveMistakeCount: number = 0
consecutiveMistakeCountForApplyDiff: Map<string, number> = new Map()
@ -332,17 +333,7 @@ export class Cline extends EventEmitter<ClineEvents> {
}
private async addToClineMessages(message: ClineMessage) {
// Find the correct position to insert the message based on timestamp
const insertIndex = this.clineMessages.findIndex((existingMsg) => existingMsg.ts > message.ts)
if (insertIndex === -1) {
// If no message with a later timestamp is found, append to the end
this.clineMessages.push(message)
} else {
// Insert the message at the correct position to maintain chronological order
this.clineMessages.splice(insertIndex, 0, message)
}
this.clineMessages.push(message)
await this.providerRef.deref()?.postStateToWebview()
this.emit("message", { action: "created", message })
await this.saveClineMessages()
@ -450,6 +441,7 @@ export class Cline extends EventEmitter<ClineEvents> {
// This is a new partial message, so add it with partial
// state.
askTs = Date.now()
this.lastMessageTs = askTs
await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text, partial })
throw new Error("Current ask promise was ignored (#2)")
}
@ -468,6 +460,8 @@ export class Cline extends EventEmitter<ClineEvents> {
So in this case we must make sure that the message ts is never altered after first setting it.
*/
askTs = lastMessage.ts
this.lastMessageTs = askTs
// lastMessage.ts = askTs
lastMessage.text = text
lastMessage.partial = false
lastMessage.progressStatus = progressStatus
@ -479,6 +473,7 @@ export class Cline extends EventEmitter<ClineEvents> {
this.askResponseText = undefined
this.askResponseImages = undefined
askTs = Date.now()
this.lastMessageTs = askTs
await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text })
}
}
@ -488,10 +483,18 @@ export class Cline extends EventEmitter<ClineEvents> {
this.askResponseText = undefined
this.askResponseImages = undefined
askTs = Date.now()
this.lastMessageTs = askTs
await this.addToClineMessages({ ts: askTs, type: "ask", ask: type, text })
}
await pWaitFor(() => this.askResponse !== undefined, { interval: 100 })
await pWaitFor(() => this.askResponse !== undefined || this.lastMessageTs !== askTs, { interval: 100 })
if (this.lastMessageTs !== askTs) {
// Could happen if we send multiple asks in a row i.e. with
// command_output. It's important that when we know an ask could
// fail, it is handled gracefully.
throw new Error("Current ask promise was ignored")
}
const result = { response: this.askResponse!, text: this.askResponseText, images: this.askResponseImages }
this.askResponse = undefined
@ -519,8 +522,6 @@ export class Cline extends EventEmitter<ClineEvents> {
throw new Error(`[Cline#say] task ${this.taskId}.${this.instanceId} aborted`)
}
const sayTs = (checkpoint?.startTime as number) ?? Date.now()
if (partial !== undefined) {
const lastMessage = this.clineMessages.at(-1)
const isUpdatingPreviousPartial =
@ -535,6 +536,8 @@ export class Cline extends EventEmitter<ClineEvents> {
this.updateClineMessage(lastMessage)
} else {
// this is a new partial message, so add it with partial state
const sayTs = Date.now()
this.lastMessageTs = sayTs
await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images, partial })
}
} else {
@ -542,6 +545,8 @@ export class Cline extends EventEmitter<ClineEvents> {
if (isUpdatingPreviousPartial) {
// This is the complete version of a previously partial
// message, so replace the partial with the complete version.
this.lastMessageTs = lastMessage.ts
// lastMessage.ts = sayTs
lastMessage.text = text
lastMessage.images = images
lastMessage.partial = false
@ -553,11 +558,15 @@ export class Cline extends EventEmitter<ClineEvents> {
this.updateClineMessage(lastMessage)
} else {
// This is a new and complete message, so add it like normal.
const sayTs = Date.now()
this.lastMessageTs = sayTs
await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images })
}
}
} else {
// this is a new non-partial message, so add it like normal
const sayTs = Date.now()
this.lastMessageTs = sayTs
await this.addToClineMessages({ ts: sayTs, type: "say", say: type, text, images, checkpoint })
}
}
@ -2394,16 +2403,14 @@ export class Cline extends EventEmitter<ClineEvents> {
}
})
service.on("checkpoint", ({ isFirst, fromHash: from, toHash: to, startTime }) => {
service.on("checkpoint", ({ isFirst, fromHash: from, toHash: to }) => {
try {
this.providerRef.deref()?.postMessageToWebview({ type: "currentCheckpointUpdated", text: to })
this.say("checkpoint_saved", to, undefined, undefined, { isFirst, from, to, startTime }).catch(
(err) => {
log("[Cline#initializeCheckpoints] caught unexpected error in say('checkpoint_saved')")
console.error(err)
},
)
this.say("checkpoint_saved", to, undefined, undefined, { isFirst, from, to }).catch((err) => {
log("[Cline#initializeCheckpoints] caught unexpected error in say('checkpoint_saved')")
console.error(err)
})
} catch (err) {
log(
"[Cline#initializeCheckpoints] caught unexpected error in on('checkpoint'), disabling checkpoints",

View file

@ -218,7 +218,7 @@ export abstract class ShadowCheckpointService extends EventEmitter {
const duration = Date.now() - startTime
if (isFirst || result.commit) {
this.emit("checkpoint", { type: "checkpoint", isFirst, fromHash, toHash, duration, startTime })
this.emit("checkpoint", { type: "checkpoint", isFirst, fromHash, toHash, duration })
}
if (result.commit) {

View file

@ -29,7 +29,6 @@ export interface CheckpointEventMap {
fromHash: string
toHash: string
duration: number
startTime: number
}
restore: { type: "restore"; commitHash: string; duration: number }
error: { type: "error"; error: Error }