mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-05 08:10:14 +00:00
feat: pause auto-approve while typing in chat input
- Auto-approve operations are now paused when there is text in the chat input box - Added visual indicator showing "Auto-approve paused while typing" when paused - Added tests to verify the pause/resume functionality - Addresses user feedback about auto-approve continuing while typing hints Fixes #8074
This commit is contained in:
parent
7b1e3a0ee5
commit
77768f836b
3 changed files with 175 additions and 0 deletions
|
|
@ -1594,6 +1594,13 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
return
|
||||
}
|
||||
|
||||
// Check if there's text in the input box - pause auto-approve if there is
|
||||
const hasInputText = inputValueRef.current.trim().length > 0
|
||||
if (hasInputText) {
|
||||
// User is typing, don't auto-approve
|
||||
return
|
||||
}
|
||||
|
||||
const autoApproveOrReject = async () => {
|
||||
// Check for auto-reject first (commands that should be denied)
|
||||
if (lastMessage?.ask === "command" && isDeniedCommand(lastMessage)) {
|
||||
|
|
@ -1703,6 +1710,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
isDeniedCommand,
|
||||
getDeniedPrefix,
|
||||
tSettings,
|
||||
inputValue, // Add inputValue dependency to re-run when input changes
|
||||
])
|
||||
|
||||
// Function to handle mode switching
|
||||
|
|
@ -1898,6 +1906,16 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
|
|||
? "opacity-100"
|
||||
: "opacity-50"
|
||||
}`}>
|
||||
{/* Show auto-approve paused indicator when there's input text */}
|
||||
{enableButtons &&
|
||||
autoApprovalEnabled &&
|
||||
hasEnabledOptions &&
|
||||
inputValue.trim().length > 0 &&
|
||||
!showScrollToBottom && (
|
||||
<div className="flex-1 text-xs text-vscode-descriptionForeground opacity-75 text-center">
|
||||
{t("chat:autoApprovePaused")}
|
||||
</div>
|
||||
)}
|
||||
{showScrollToBottom ? (
|
||||
<StandardTooltip content={t("chat:scrollToBottom")}>
|
||||
<VSCodeButton
|
||||
|
|
|
|||
|
|
@ -671,4 +671,160 @@ describe("ChatView - Auto Approval Tests", () => {
|
|||
askResponse: "yesButtonClicked",
|
||||
})
|
||||
})
|
||||
|
||||
it("does not auto-approve when there is text in the input box", async () => {
|
||||
const { container } = renderChatView()
|
||||
|
||||
// First hydrate state with initial task
|
||||
mockPostMessage({
|
||||
alwaysAllowReadOnly: true,
|
||||
autoApprovalEnabled: true,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Simulate typing in the input box
|
||||
const textarea = container.querySelector("textarea")
|
||||
if (textarea) {
|
||||
// Simulate user typing
|
||||
Object.defineProperty(textarea, "value", {
|
||||
writable: true,
|
||||
value: "User is typing something...",
|
||||
})
|
||||
// Trigger input event
|
||||
const inputEvent = new Event("input", { bubbles: true })
|
||||
textarea.dispatchEvent(inputEvent)
|
||||
}
|
||||
|
||||
// Then send the read tool ask message
|
||||
mockPostMessage({
|
||||
alwaysAllowReadOnly: true,
|
||||
autoApprovalEnabled: true,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
{
|
||||
type: "ask",
|
||||
ask: "tool",
|
||||
ts: Date.now(),
|
||||
text: JSON.stringify({ tool: "readFile", path: "test.txt" }),
|
||||
partial: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Wait a short time and verify no auto-approval message was sent
|
||||
await new Promise((resolve) => setTimeout(resolve, 200))
|
||||
expect(vscode.postMessage).not.toHaveBeenCalledWith({
|
||||
type: "askResponse",
|
||||
askResponse: "yesButtonClicked",
|
||||
})
|
||||
})
|
||||
|
||||
it("resumes auto-approve when input text is cleared", async () => {
|
||||
const { container } = renderChatView()
|
||||
|
||||
// First hydrate state with initial task
|
||||
mockPostMessage({
|
||||
alwaysAllowReadOnly: true,
|
||||
autoApprovalEnabled: true,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Simulate typing in the input box
|
||||
const textarea = container.querySelector("textarea")
|
||||
if (textarea) {
|
||||
// First add text
|
||||
Object.defineProperty(textarea, "value", {
|
||||
writable: true,
|
||||
value: "User is typing...",
|
||||
})
|
||||
const inputEvent = new Event("input", { bubbles: true })
|
||||
textarea.dispatchEvent(inputEvent)
|
||||
}
|
||||
|
||||
// Send a tool ask message while text is present
|
||||
mockPostMessage({
|
||||
alwaysAllowReadOnly: true,
|
||||
autoApprovalEnabled: true,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
{
|
||||
type: "ask",
|
||||
ask: "tool",
|
||||
ts: Date.now() - 100,
|
||||
text: JSON.stringify({ tool: "readFile", path: "test1.txt" }),
|
||||
partial: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Wait and verify no auto-approval
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
expect(vscode.postMessage).not.toHaveBeenCalledWith({
|
||||
type: "askResponse",
|
||||
askResponse: "yesButtonClicked",
|
||||
})
|
||||
|
||||
// Now clear the input
|
||||
if (textarea) {
|
||||
Object.defineProperty(textarea, "value", {
|
||||
writable: true,
|
||||
value: "",
|
||||
})
|
||||
const clearEvent = new Event("input", { bubbles: true })
|
||||
textarea.dispatchEvent(clearEvent)
|
||||
}
|
||||
|
||||
// Send another tool ask message after clearing text
|
||||
mockPostMessage({
|
||||
alwaysAllowReadOnly: true,
|
||||
autoApprovalEnabled: true,
|
||||
clineMessages: [
|
||||
{
|
||||
type: "say",
|
||||
say: "task",
|
||||
ts: Date.now() - 2000,
|
||||
text: "Initial task",
|
||||
},
|
||||
{
|
||||
type: "ask",
|
||||
ask: "tool",
|
||||
ts: Date.now(),
|
||||
text: JSON.stringify({ tool: "readFile", path: "test2.txt" }),
|
||||
partial: false,
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
// Now it should auto-approve since input is cleared
|
||||
await waitFor(() => {
|
||||
expect(vscode.postMessage).toHaveBeenCalledWith({
|
||||
type: "askResponse",
|
||||
askResponse: "yesButtonClicked",
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -272,6 +272,7 @@
|
|||
},
|
||||
"autoApprove": {
|
||||
"tooltipManage": "Manage auto-approval settings",
|
||||
"autoApprovePaused": "Auto-approve paused while typing",
|
||||
"tooltipStatus": "Auto-approval enabled for: {{toggles}}",
|
||||
"title": "Auto-approve",
|
||||
"all": "All",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue