mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix(task): drain queued messages while waiting for ask (#10315)
This commit is contained in:
parent
53e1ff0058
commit
dfa7c357c2
2 changed files with 69 additions and 1 deletions
|
|
@ -1241,7 +1241,37 @@ export class Task extends EventEmitter<TaskEvents> implements TaskLike {
|
|||
}
|
||||
|
||||
// Wait for askResponse to be set
|
||||
await pWaitFor(() => this.askResponse !== undefined || this.lastMessageTs !== askTs, { interval: 100 })
|
||||
await pWaitFor(
|
||||
() => {
|
||||
if (this.askResponse !== undefined || this.lastMessageTs !== askTs) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If a queued message arrives while we're blocked on an ask (e.g. a follow-up
|
||||
// suggestion click that was incorrectly queued due to UI state), consume it
|
||||
// immediately so the task doesn't hang.
|
||||
if (!this.messageQueueService.isEmpty()) {
|
||||
const message = this.messageQueueService.dequeueMessage()
|
||||
if (message) {
|
||||
// If this is a tool approval ask, we need to approve first (yesButtonClicked)
|
||||
// and include any queued text/images.
|
||||
if (
|
||||
type === "tool" ||
|
||||
type === "command" ||
|
||||
type === "browser_action_launch" ||
|
||||
type === "use_mcp_server"
|
||||
) {
|
||||
this.handleWebviewAskResponse("yesButtonClicked", message.text, message.images)
|
||||
} else {
|
||||
this.handleWebviewAskResponse("messageResponse", message.text, message.images)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
},
|
||||
{ interval: 100 },
|
||||
)
|
||||
|
||||
if (this.lastMessageTs !== askTs) {
|
||||
// Could happen if we send multiple asks in a row i.e. with
|
||||
|
|
|
|||
38
src/core/task/__tests__/ask-queued-message-drain.spec.ts
Normal file
38
src/core/task/__tests__/ask-queued-message-drain.spec.ts
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
import { Task } from "../Task"
|
||||
|
||||
// Keep this test focused: if a queued message arrives while Task.ask() is blocked,
|
||||
// it should be consumed and used to fulfill the ask.
|
||||
|
||||
describe("Task.ask queued message drain", () => {
|
||||
it("consumes queued message while blocked on followup ask", async () => {
|
||||
const task = Object.create(Task.prototype) as Task
|
||||
;(task as any).abort = false
|
||||
;(task as any).clineMessages = []
|
||||
;(task as any).askResponse = undefined
|
||||
;(task as any).askResponseText = undefined
|
||||
;(task as any).askResponseImages = undefined
|
||||
;(task as any).lastMessageTs = undefined
|
||||
|
||||
// Message queue service exists in constructor; for unit test we can attach a real one.
|
||||
const { MessageQueueService } = await import("../../message-queue/MessageQueueService")
|
||||
;(task as any).messageQueueService = new MessageQueueService()
|
||||
|
||||
// Minimal stubs used by ask()
|
||||
;(task as any).addToClineMessages = vi.fn(async () => {})
|
||||
;(task as any).saveClineMessages = vi.fn(async () => {})
|
||||
;(task as any).updateClineMessage = vi.fn(async () => {})
|
||||
;(task as any).cancelAutoApprovalTimeout = vi.fn(() => {})
|
||||
;(task as any).checkpointSave = vi.fn(async () => {})
|
||||
;(task as any).emit = vi.fn()
|
||||
;(task as any).providerRef = { deref: () => undefined }
|
||||
|
||||
const askPromise = task.ask("followup", "Q?", false)
|
||||
|
||||
// Simulate webview queuing the user's selection text while the ask is pending.
|
||||
;(task as any).messageQueueService.addMessage("picked answer")
|
||||
|
||||
const result = await askPromise
|
||||
expect(result.response).toBe("messageResponse")
|
||||
expect(result.text).toBe("picked answer")
|
||||
})
|
||||
})
|
||||
Loading…
Add table
Reference in a new issue