Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1538,6 +1538,10 @@ export class ClineProvider
}
await task.condenseContext()
await this.postMessageToWebview({ type: "condenseTaskContextResponse", text: taskId })

// Process any queued messages after condensation completes
// This ensures messages sent during condensation are not lost
task.processQueuedMessages()
}

// this function deletes a task from task hidtory, and deletes it's checkpoints and delete the task folder
Expand Down
84 changes: 84 additions & 0 deletions src/core/webview/__tests__/ClineProvider.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3852,4 +3852,88 @@ describe("ClineProvider - Comprehensive Edit/Delete Edge Cases", () => {
})
})
})

describe("condenseTaskContext", () => {
test("processes queued messages after condensation completes", async () => {
// Setup a task with mocked methods
const mockTask = new Task(defaultTaskOptions)
const taskId = "test-task-id"
Object.defineProperty(mockTask, "taskId", { value: taskId, writable: true })

// Add the condenseContext method to the mock task
mockTask.condenseContext = vi.fn().mockResolvedValue(undefined)

// Add the processQueuedMessages method to the mock task
mockTask.processQueuedMessages = vi.fn().mockImplementation(() => {})

// Mock the message queue service to have queued messages
const mockMessageQueueService = {
isEmpty: vi.fn().mockReturnValue(false),
messages: [
{ id: "msg1", text: "Queued message 1", images: [] },
{ id: "msg2", text: "Queued message 2", images: [] },
],
dequeueMessage: vi.fn().mockReturnValueOnce({ text: "Queued message 1", images: [] }),
}
Object.defineProperty(mockTask, "messageQueueService", { value: mockMessageQueueService, writable: true })

// Add task to provider stack
await provider.addClineToStack(mockTask)

// Mock postMessageToWebview
const postMessageSpy = vi.spyOn(provider, "postMessageToWebview").mockResolvedValue(undefined)

// Call condenseTaskContext
await provider.condenseTaskContext(taskId)

// Verify the expected sequence of calls
expect(mockTask.condenseContext).toHaveBeenCalled()
expect(postMessageSpy).toHaveBeenCalledWith({ type: "condenseTaskContextResponse", text: taskId })
expect(mockTask.processQueuedMessages).toHaveBeenCalled()
})

test("throws error when task is not found", async () => {
const nonExistentTaskId = "non-existent-task"

// Attempt to condense context for non-existent task
await expect(provider.condenseTaskContext(nonExistentTaskId)).rejects.toThrow(
`Task with id ${nonExistentTaskId} not found in stack`,
)
})

test("handles empty message queue correctly", async () => {
// Setup a task with empty message queue
const mockTask = new Task(defaultTaskOptions)
const taskId = "test-task-id-empty-queue"
Object.defineProperty(mockTask, "taskId", { value: taskId, writable: true })

// Add the condenseContext method to the mock task
mockTask.condenseContext = vi.fn().mockResolvedValue(undefined)

// Add the processQueuedMessages method to the mock task
mockTask.processQueuedMessages = vi.fn().mockImplementation(() => {})

// Mock empty message queue
const mockMessageQueueService = {
isEmpty: vi.fn().mockReturnValue(true),
messages: [],
dequeueMessage: vi.fn().mockReturnValue(undefined),
}
Object.defineProperty(mockTask, "messageQueueService", { value: mockMessageQueueService, writable: true })

// Add task to provider stack
await provider.addClineToStack(mockTask)

// Mock postMessageToWebview
const postMessageSpy = vi.spyOn(provider, "postMessageToWebview").mockResolvedValue(undefined)

// Call condenseTaskContext
await provider.condenseTaskContext(taskId)

// Verify calls were made even with empty queue
expect(mockTask.condenseContext).toHaveBeenCalled()
expect(postMessageSpy).toHaveBeenCalledWith({ type: "condenseTaskContextResponse", text: taskId })
expect(mockTask.processQueuedMessages).toHaveBeenCalled()
})
})
})