mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix: prevent enhance prompt from overwriting both edit and new message boxes
- Add context parameter to enhance prompt messages to distinguish between main and edit mode - Update ChatTextArea to only respond to enhance prompt messages matching its context - Add comprehensive test coverage for context-specific behavior Fixes #8553
This commit is contained in:
parent
5a3f911321
commit
994e2a26c5
3 changed files with 127 additions and 23 deletions
|
|
@ -1694,7 +1694,12 @@ export const webviewMessageHandler = async (
|
|||
if (result.success && result.enhancedText) {
|
||||
// Capture telemetry for prompt enhancement
|
||||
MessageEnhancer.captureTelemetry(currentCline?.taskId, includeTaskHistoryInEnhance)
|
||||
await provider.postMessageToWebview({ type: "enhancedPrompt", text: result.enhancedText })
|
||||
// Include the context from the original request in the response
|
||||
await provider.postMessageToWebview({
|
||||
type: "enhancedPrompt",
|
||||
text: result.enhancedText,
|
||||
context: message.context,
|
||||
})
|
||||
} else {
|
||||
throw new Error(result.error || "Unknown error")
|
||||
}
|
||||
|
|
@ -1704,7 +1709,11 @@ export const webviewMessageHandler = async (
|
|||
)
|
||||
|
||||
vscode.window.showErrorMessage(t("common:errors.enhance_prompt"))
|
||||
await provider.postMessageToWebview({ type: "enhancedPrompt" })
|
||||
// Include context even in error response
|
||||
await provider.postMessageToWebview({
|
||||
type: "enhancedPrompt",
|
||||
context: message.context,
|
||||
})
|
||||
}
|
||||
}
|
||||
break
|
||||
|
|
|
|||
|
|
@ -124,28 +124,33 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
const message = event.data
|
||||
|
||||
if (message.type === "enhancedPrompt") {
|
||||
if (message.text && textAreaRef.current) {
|
||||
try {
|
||||
// Use execCommand to replace text while preserving undo history
|
||||
if (document.execCommand) {
|
||||
// Use native browser methods to preserve undo stack
|
||||
const textarea = textAreaRef.current
|
||||
// Only handle the enhanced prompt if it's for this specific textarea instance
|
||||
// Edit mode textareas have context "edit", main textarea has context "main"
|
||||
const expectedContext = isEditMode ? "edit" : "main"
|
||||
if (message.context === expectedContext) {
|
||||
if (message.text && textAreaRef.current) {
|
||||
try {
|
||||
// Use execCommand to replace text while preserving undo history
|
||||
if (document.execCommand) {
|
||||
// Use native browser methods to preserve undo stack
|
||||
const textarea = textAreaRef.current
|
||||
|
||||
// Focus the textarea to ensure it's the active element
|
||||
textarea.focus()
|
||||
// Focus the textarea to ensure it's the active element
|
||||
textarea.focus()
|
||||
|
||||
// Select all text first
|
||||
textarea.select()
|
||||
document.execCommand("insertText", false, message.text)
|
||||
} else {
|
||||
// Select all text first
|
||||
textarea.select()
|
||||
document.execCommand("insertText", false, message.text)
|
||||
} else {
|
||||
setInputValue(message.text)
|
||||
}
|
||||
} catch {
|
||||
setInputValue(message.text)
|
||||
}
|
||||
} catch {
|
||||
setInputValue(message.text)
|
||||
}
|
||||
}
|
||||
|
||||
setIsEnhancingPrompt(false)
|
||||
setIsEnhancingPrompt(false)
|
||||
}
|
||||
} else if (message.type === "insertTextIntoTextarea") {
|
||||
if (message.text && textAreaRef.current) {
|
||||
// Insert the command text at the current cursor position
|
||||
|
|
@ -196,7 +201,7 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
|
||||
window.addEventListener("message", messageHandler)
|
||||
return () => window.removeEventListener("message", messageHandler)
|
||||
}, [setInputValue, searchRequestId, inputValue])
|
||||
}, [setInputValue, searchRequestId, inputValue, isEditMode])
|
||||
|
||||
const [isDraggingOver, setIsDraggingOver] = useState(false)
|
||||
const [textAreaBaseHeight, setTextAreaBaseHeight] = useState<number | undefined>(undefined)
|
||||
|
|
@ -239,11 +244,13 @@ export const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
|
||||
if (trimmedInput) {
|
||||
setIsEnhancingPrompt(true)
|
||||
vscode.postMessage({ type: "enhancePrompt" as const, text: trimmedInput })
|
||||
// Include context to identify which textarea is requesting enhancement
|
||||
const context = isEditMode ? "edit" : "main"
|
||||
vscode.postMessage({ type: "enhancePrompt" as const, text: trimmedInput, context })
|
||||
} else {
|
||||
setInputValue(t("chat:enhancePromptDescription"))
|
||||
}
|
||||
}, [inputValue, setInputValue, t])
|
||||
}, [inputValue, setInputValue, t, isEditMode])
|
||||
|
||||
const allModes = useMemo(() => getAllModes(customModes), [customModes])
|
||||
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ describe("ChatTextArea", () => {
|
|||
expect(mockPostMessage).toHaveBeenCalledWith({
|
||||
type: "enhancePrompt",
|
||||
text: "Test prompt",
|
||||
context: "main",
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -183,7 +184,7 @@ describe("ChatTextArea", () => {
|
|||
})
|
||||
|
||||
describe("enhanced prompt response", () => {
|
||||
it("should update input value using native browser methods when receiving enhanced prompt", () => {
|
||||
it("should update input value using native browser methods when receiving enhanced prompt with matching context", () => {
|
||||
const setInputValue = vi.fn()
|
||||
|
||||
// Mock document.execCommand
|
||||
|
|
@ -205,12 +206,13 @@ describe("ChatTextArea", () => {
|
|||
textarea.select = mockSelect
|
||||
textarea.focus = mockFocus
|
||||
|
||||
// Simulate receiving enhanced prompt message
|
||||
// Simulate receiving enhanced prompt message with matching context
|
||||
window.dispatchEvent(
|
||||
new MessageEvent("message", {
|
||||
data: {
|
||||
type: "enhancedPrompt",
|
||||
text: "Enhanced test prompt",
|
||||
context: "main",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
|
@ -221,6 +223,90 @@ describe("ChatTextArea", () => {
|
|||
expect(mockExecCommand).toHaveBeenCalledWith("insertText", false, "Enhanced test prompt")
|
||||
})
|
||||
|
||||
it("should ignore enhanced prompt with non-matching context", () => {
|
||||
const setInputValue = vi.fn()
|
||||
|
||||
// Mock document.execCommand
|
||||
const mockExecCommand = vi.fn().mockReturnValue(true)
|
||||
Object.defineProperty(document, "execCommand", {
|
||||
value: mockExecCommand,
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const { container } = render(
|
||||
<ChatTextArea {...defaultProps} setInputValue={setInputValue} inputValue="Original prompt" />,
|
||||
)
|
||||
|
||||
const textarea = container.querySelector("textarea")!
|
||||
|
||||
// Mock textarea methods
|
||||
const mockSelect = vi.fn()
|
||||
const mockFocus = vi.fn()
|
||||
textarea.select = mockSelect
|
||||
textarea.focus = mockFocus
|
||||
|
||||
// Simulate receiving enhanced prompt message with non-matching context (edit instead of main)
|
||||
window.dispatchEvent(
|
||||
new MessageEvent("message", {
|
||||
data: {
|
||||
type: "enhancedPrompt",
|
||||
text: "Enhanced test prompt",
|
||||
context: "edit",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
// Verify native browser methods were NOT called
|
||||
expect(mockFocus).not.toHaveBeenCalled()
|
||||
expect(mockSelect).not.toHaveBeenCalled()
|
||||
expect(mockExecCommand).not.toHaveBeenCalled()
|
||||
expect(setInputValue).not.toHaveBeenCalled()
|
||||
})
|
||||
|
||||
it("should handle enhanced prompt for edit mode", () => {
|
||||
const setInputValue = vi.fn()
|
||||
|
||||
// Mock document.execCommand
|
||||
const mockExecCommand = vi.fn().mockReturnValue(true)
|
||||
Object.defineProperty(document, "execCommand", {
|
||||
value: mockExecCommand,
|
||||
writable: true,
|
||||
})
|
||||
|
||||
const { container } = render(
|
||||
<ChatTextArea
|
||||
{...defaultProps}
|
||||
setInputValue={setInputValue}
|
||||
inputValue="Original prompt"
|
||||
isEditMode={true}
|
||||
/>,
|
||||
)
|
||||
|
||||
const textarea = container.querySelector("textarea")!
|
||||
|
||||
// Mock textarea methods
|
||||
const mockSelect = vi.fn()
|
||||
const mockFocus = vi.fn()
|
||||
textarea.select = mockSelect
|
||||
textarea.focus = mockFocus
|
||||
|
||||
// Simulate receiving enhanced prompt message with edit context
|
||||
window.dispatchEvent(
|
||||
new MessageEvent("message", {
|
||||
data: {
|
||||
type: "enhancedPrompt",
|
||||
text: "Enhanced test prompt",
|
||||
context: "edit",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
||||
// Verify native browser methods were called for edit mode
|
||||
expect(mockFocus).toHaveBeenCalled()
|
||||
expect(mockSelect).toHaveBeenCalled()
|
||||
expect(mockExecCommand).toHaveBeenCalledWith("insertText", false, "Enhanced test prompt")
|
||||
})
|
||||
|
||||
it("should fallback to setInputValue when execCommand is not available", () => {
|
||||
const setInputValue = vi.fn()
|
||||
|
||||
|
|
@ -238,6 +324,7 @@ describe("ChatTextArea", () => {
|
|||
data: {
|
||||
type: "enhancedPrompt",
|
||||
text: "Enhanced test prompt",
|
||||
context: "main",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
|
@ -258,6 +345,7 @@ describe("ChatTextArea", () => {
|
|||
data: {
|
||||
type: "enhancedPrompt",
|
||||
text: "Enhanced test prompt",
|
||||
context: "main",
|
||||
},
|
||||
}),
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue