Skip to content

Commit f49fd8e

Browse files
committed
fix: process queued messages after context condensation
- Added processQueuedMessages() call after condenseContext completes - Ensures messages sent during condensation are not lost - Added comprehensive tests for the fix Fixes #8526
1 parent 85b0e8a commit f49fd8e

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

src/core/webview/ClineProvider.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,6 +1538,10 @@ export class ClineProvider
15381538
}
15391539
await task.condenseContext()
15401540
await this.postMessageToWebview({ type: "condenseTaskContextResponse", text: taskId })
1541+
1542+
// Process any queued messages after condensation completes
1543+
// This ensures messages sent during condensation are not lost
1544+
task.processQueuedMessages()
15411545
}
15421546

15431547
// this function deletes a task from task hidtory, and deletes it's checkpoints and delete the task folder

src/core/webview/__tests__/ClineProvider.spec.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3852,4 +3852,88 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
38523852
})
38533853
})
38543854
})
3855+
3856+
describe("condenseTaskContext", () => {
3857+
test("processes queued messages after condensation completes", async () => {
3858+
// Setup a task with mocked methods
3859+
const mockTask = new Task(defaultTaskOptions)
3860+
const taskId = "test-task-id"
3861+
Object.defineProperty(mockTask, "taskId", { value: taskId, writable: true })
3862+
3863+
// Add the condenseContext method to the mock task
3864+
mockTask.condenseContext = vi.fn().mockResolvedValue(undefined)
3865+
3866+
// Add the processQueuedMessages method to the mock task
3867+
mockTask.processQueuedMessages = vi.fn().mockImplementation(() => {})
3868+
3869+
// Mock the message queue service to have queued messages
3870+
const mockMessageQueueService = {
3871+
isEmpty: vi.fn().mockReturnValue(false),
3872+
messages: [
3873+
{ id: "msg1", text: "Queued message 1", images: [] },
3874+
{ id: "msg2", text: "Queued message 2", images: [] },
3875+
],
3876+
dequeueMessage: vi.fn().mockReturnValueOnce({ text: "Queued message 1", images: [] }),
3877+
}
3878+
Object.defineProperty(mockTask, "messageQueueService", { value: mockMessageQueueService, writable: true })
3879+
3880+
// Add task to provider stack
3881+
await provider.addClineToStack(mockTask)
3882+
3883+
// Mock postMessageToWebview
3884+
const postMessageSpy = vi.spyOn(provider, "postMessageToWebview").mockResolvedValue(undefined)
3885+
3886+
// Call condenseTaskContext
3887+
await provider.condenseTaskContext(taskId)
3888+
3889+
// Verify the expected sequence of calls
3890+
expect(mockTask.condenseContext).toHaveBeenCalled()
3891+
expect(postMessageSpy).toHaveBeenCalledWith({ type: "condenseTaskContextResponse", text: taskId })
3892+
expect(mockTask.processQueuedMessages).toHaveBeenCalled()
3893+
})
3894+
3895+
test("throws error when task is not found", async () => {
3896+
const nonExistentTaskId = "non-existent-task"
3897+
3898+
// Attempt to condense context for non-existent task
3899+
await expect(provider.condenseTaskContext(nonExistentTaskId)).rejects.toThrow(
3900+
`Task with id ${nonExistentTaskId} not found in stack`,
3901+
)
3902+
})
3903+
3904+
test("handles empty message queue correctly", async () => {
3905+
// Setup a task with empty message queue
3906+
const mockTask = new Task(defaultTaskOptions)
3907+
const taskId = "test-task-id-empty-queue"
3908+
Object.defineProperty(mockTask, "taskId", { value: taskId, writable: true })
3909+
3910+
// Add the condenseContext method to the mock task
3911+
mockTask.condenseContext = vi.fn().mockResolvedValue(undefined)
3912+
3913+
// Add the processQueuedMessages method to the mock task
3914+
mockTask.processQueuedMessages = vi.fn().mockImplementation(() => {})
3915+
3916+
// Mock empty message queue
3917+
const mockMessageQueueService = {
3918+
isEmpty: vi.fn().mockReturnValue(true),
3919+
messages: [],
3920+
dequeueMessage: vi.fn().mockReturnValue(undefined),
3921+
}
3922+
Object.defineProperty(mockTask, "messageQueueService", { value: mockMessageQueueService, writable: true })
3923+
3924+
// Add task to provider stack
3925+
await provider.addClineToStack(mockTask)
3926+
3927+
// Mock postMessageToWebview
3928+
const postMessageSpy = vi.spyOn(provider, "postMessageToWebview").mockResolvedValue(undefined)
3929+
3930+
// Call condenseTaskContext
3931+
await provider.condenseTaskContext(taskId)
3932+
3933+
// Verify calls were made even with empty queue
3934+
expect(mockTask.condenseContext).toHaveBeenCalled()
3935+
expect(postMessageSpy).toHaveBeenCalledWith({ type: "condenseTaskContextResponse", text: taskId })
3936+
expect(mockTask.processQueuedMessages).toHaveBeenCalled()
3937+
})
3938+
})
38553939
})

0 commit comments

Comments
 (0)