mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-06 02:47:56 +00:00
fix: queue messages during command execution instead of losing them (#11140)
This commit is contained in:
parent
8cf82cd3a9
commit
ede1d29299
2 changed files with 81 additions and 3 deletions
|
|
@ -612,7 +612,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
// - Task is busy (sendingDisabled)
|
||||
// - API request in progress (isStreaming)
|
||||
// - Queue has items (preserve message order during drain)
|
||||
if (sendingDisabled || isStreaming || messageQueue.length > 0) {
|
||||
// - Command is running (command_output) - user's message should be queued for AI, not sent to terminal
|
||||
if (
|
||||
sendingDisabled ||
|
||||
isStreaming ||
|
||||
messageQueue.length > 0 ||
|
||||
clineAskRef.current === "command_output"
|
||||
) {
|
||||
try {
|
||||
console.log("queueMessage", text, images)
|
||||
vscode.postMessage({ type: "queueMessage", text, images })
|
||||
|
|
@ -645,7 +651,6 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
case "tool":
|
||||
case "browser_action_launch":
|
||||
case "command": // User can provide feedback to a tool or command use.
|
||||
case "command_output": // User can send input to command stdin.
|
||||
case "use_mcp_server":
|
||||
case "completion_result": // If this happens then the user has feedback for the completion result.
|
||||
case "resume_task":
|
||||
|
|
@ -1496,9 +1501,20 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
|
||||
useImperativeHandle(ref, () => ({
|
||||
acceptInput: () => {
|
||||
const hasInput = inputValue.trim() || selectedImages.length > 0
|
||||
|
||||
// Special case: during command_output, queue the message instead of
|
||||
// triggering the primary button action (which would lose the message)
|
||||
if (clineAskRef.current === "command_output" && hasInput) {
|
||||
vscode.postMessage({ type: "queueMessage", text: inputValue.trim(), images: selectedImages })
|
||||
setInputValue("")
|
||||
setSelectedImages([])
|
||||
return
|
||||
}
|
||||
|
||||
if (enableButtons && primaryButtonText) {
|
||||
handlePrimaryButtonClick(inputValue, selectedImages)
|
||||
} else if (!sendingDisabled && !isProfileDisabled && (inputValue.trim() || selectedImages.length > 0)) {
|
||||
} else if (!sendingDisabled && !isProfileDisabled && hasInput) {
|
||||
handleSendMessage(inputValue, selectedImages)
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,68 @@ describe("ChatView - Message Queueing Tests", () => {
|
|||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it("queues messages during command_output state instead of losing them", async () => {
|
||||
const { getByTestId } = renderChatView()
|
||||
|
||||
// Hydrate state with command_output ask (Proceed While Running state)
|
||||
mockPostMessage({
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
{
|
||||
type: "ask",
|
||||
ask: "command_output",
|
||||
ts: Date.now(),
|
||||
text: "",
|
||||
partial: false, // Non-partial so buttons are enabled
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Wait for state to be updated - need to allow time for React effects to propagate
|
||||
// (clineAsk state update -> clineAskRef.current update)
|
||||
await waitFor(() => {
|
||||
expect(getByTestId("chat-textarea")).toBeInTheDocument()
|
||||
})
|
||||
|
||||
// Allow React effects to complete (clineAsk -> clineAskRef sync)
|
||||
await act(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 50))
|
||||
})
|
||||
|
||||
// Clear message calls before simulating user input
|
||||
vi.mocked(vscode.postMessage).mockClear()
|
||||
|
||||
// Simulate user typing and sending a message during command execution
|
||||
const chatTextArea = getByTestId("chat-textarea")
|
||||
const input = chatTextArea.querySelector("input")! as HTMLInputElement
|
||||
|
||||
await act(async () => {
|
||||
fireEvent.change(input, { target: { value: "message during command execution" } })
|
||||
fireEvent.keyDown(input, { key: "Enter", code: "Enter" })
|
||||
})
|
||||
|
||||
// Verify that the message was queued (not lost via terminalOperation)
|
||||
await waitFor(() => {
|
||||
expect(vscode.postMessage).toHaveBeenCalledWith({
|
||||
type: "queueMessage",
|
||||
text: "message during command execution",
|
||||
images: [],
|
||||
})
|
||||
})
|
||||
|
||||
// Verify it was NOT sent as terminalOperation (which would lose the message)
|
||||
expect(vscode.postMessage).not.toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
type: "terminalOperation",
|
||||
}),
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("ChatView - Context Condensing Indicator Tests", () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue