mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-05 08:10:14 +00:00
fix: preserve user messages at choice prompts in history (fixes #7316)
- Added local message history buffer in usePromptHistory hook to store messages immediately upon sending - Modified ChatTextArea to save messages to local history before clearing input field - Ensured messages typed at follow-up question prompts are preserved and accessible via up-arrow navigation - Added deduplication logic to prevent duplicate entries when messages are confirmed by backend This fix ensures that user messages are never lost, even if typed at choice prompts or if backend processing fails.
This commit is contained in:
parent
9b8f3b95ec
commit
7edeb0d1e5
2 changed files with 57 additions and 10 deletions
|
|
@ -215,13 +215,14 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
const [isFocused, setIsFocused] = useState(false)
|
||||
|
||||
// Use custom hook for prompt history navigation
|
||||
const { handleHistoryNavigation, resetHistoryNavigation, resetOnInputChange } = usePromptHistory({
|
||||
clineMessages,
|
||||
taskHistory,
|
||||
cwd,
|
||||
inputValue,
|
||||
setInputValue,
|
||||
})
|
||||
const { handleHistoryNavigation, resetHistoryNavigation, resetOnInputChange, addToLocalHistory } =
|
||||
usePromptHistory({
|
||||
clineMessages,
|
||||
taskHistory,
|
||||
cwd,
|
||||
inputValue,
|
||||
setInputValue,
|
||||
})
|
||||
|
||||
// Fetch git commits when Git is selected or when typing a hash.
|
||||
useEffect(() => {
|
||||
|
|
@ -465,6 +466,11 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
if (event.key === "Enter" && !event.shiftKey && !isComposing) {
|
||||
event.preventDefault()
|
||||
|
||||
// Add to local history before sending
|
||||
if (inputValue.trim()) {
|
||||
addToLocalHistory(inputValue.trim())
|
||||
}
|
||||
|
||||
// Always call onSend - let ChatView handle queueing when disabled
|
||||
resetHistoryNavigation()
|
||||
onSend()
|
||||
|
|
@ -531,6 +537,7 @@ const ChatTextArea = forwardRef<HTMLTextAreaElement, ChatTextAreaProps>(
|
|||
handleHistoryNavigation,
|
||||
resetHistoryNavigation,
|
||||
commands,
|
||||
addToLocalHistory,
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ export interface UsePromptHistoryReturn {
|
|||
) => boolean
|
||||
resetHistoryNavigation: () => void
|
||||
resetOnInputChange: () => void
|
||||
addToLocalHistory: (message: string) => void
|
||||
}
|
||||
|
||||
export const usePromptHistory = ({
|
||||
|
|
@ -38,6 +39,8 @@ export const usePromptHistory = ({
|
|||
const [historyIndex, setHistoryIndex] = useState(-1)
|
||||
const [tempInput, setTempInput] = useState("")
|
||||
const [promptHistory, setPromptHistory] = useState<string[]>([])
|
||||
// Local sent messages that haven't been confirmed by backend yet
|
||||
const [localSentMessages, setLocalSentMessages] = useState<string[]>([])
|
||||
|
||||
// Initialize prompt history with hybrid approach: conversation messages if in task, otherwise task history
|
||||
const filteredPromptHistory = useMemo(() => {
|
||||
|
|
@ -46,9 +49,30 @@ export const usePromptHistory = ({
|
|||
?.filter((message) => message.type === "say" && message.say === "user_feedback" && message.text?.trim())
|
||||
.map((message) => message.text!)
|
||||
|
||||
// If we have conversation messages, use those (newest first when navigating up)
|
||||
// Combine conversation prompts with local sent messages (deduplicated)
|
||||
const allPrompts: string[] = []
|
||||
const seen = new Set<string>()
|
||||
|
||||
// Add conversation prompts first
|
||||
if (conversationPrompts?.length) {
|
||||
return conversationPrompts.slice(-MAX_PROMPT_HISTORY_SIZE).reverse()
|
||||
conversationPrompts.forEach((prompt) => {
|
||||
if (!seen.has(prompt)) {
|
||||
seen.add(prompt)
|
||||
allPrompts.push(prompt)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Add local sent messages that aren't in conversation yet
|
||||
localSentMessages.forEach((msg) => {
|
||||
if (!seen.has(msg)) {
|
||||
allPrompts.push(msg)
|
||||
}
|
||||
})
|
||||
|
||||
// If we have any prompts, use those (newest first when navigating up)
|
||||
if (allPrompts.length) {
|
||||
return allPrompts.slice(-MAX_PROMPT_HISTORY_SIZE).reverse()
|
||||
}
|
||||
|
||||
// If we have clineMessages array (meaning we're in an active task), don't fall back to task history
|
||||
|
|
@ -67,7 +91,7 @@ export const usePromptHistory = ({
|
|||
.filter((item) => item.task?.trim() && (!item.workspace || item.workspace === cwd))
|
||||
.map((item) => item.task)
|
||||
.slice(0, MAX_PROMPT_HISTORY_SIZE)
|
||||
}, [clineMessages, taskHistory, cwd])
|
||||
}, [clineMessages, taskHistory, cwd, localSentMessages])
|
||||
|
||||
// Update prompt history when filtered history changes and reset navigation
|
||||
useEffect(() => {
|
||||
|
|
@ -175,6 +199,21 @@ export const usePromptHistory = ({
|
|||
setTempInput("")
|
||||
}, [])
|
||||
|
||||
// Add a message to local sent history
|
||||
const addToLocalHistory = useCallback((message: string) => {
|
||||
if (message?.trim()) {
|
||||
setLocalSentMessages((prev) => [...prev, message].slice(-MAX_PROMPT_HISTORY_SIZE))
|
||||
}
|
||||
}, [])
|
||||
|
||||
// Clear local sent messages when task changes
|
||||
useEffect(() => {
|
||||
// When clineMessages changes significantly (new task), clear local messages
|
||||
if (!clineMessages?.length) {
|
||||
setLocalSentMessages([])
|
||||
}
|
||||
}, [clineMessages?.length])
|
||||
|
||||
return {
|
||||
historyIndex,
|
||||
setHistoryIndex,
|
||||
|
|
@ -184,5 +223,6 @@ export const usePromptHistory = ({
|
|||
handleHistoryNavigation,
|
||||
resetHistoryNavigation,
|
||||
resetOnInputChange,
|
||||
addToLocalHistory,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue