fix: remove chat message on GUI (#5114)
* fix: remove chat message on GUI * Update web-app/src/containers/ThreadContent.tsx Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> * chore: fix message removal sequence * chore: add comment * Update web-app/src/containers/ThreadContent.tsx Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com> --------- Co-authored-by: ellipsis-dev[bot] <65095814+ellipsis-dev[bot]@users.noreply.github.com>
This commit is contained in:
parent
bbfc754fa4
commit
c6ce193256
@ -24,10 +24,6 @@ import { useModelProvider } from '@/hooks/useModelProvider'
|
|||||||
|
|
||||||
import { useAppState } from '@/hooks/useAppState'
|
import { useAppState } from '@/hooks/useAppState'
|
||||||
import { MovingBorder } from './MovingBorder'
|
import { MovingBorder } from './MovingBorder'
|
||||||
import { MCPTool } from '@/types/completion'
|
|
||||||
import { listen } from '@tauri-apps/api/event'
|
|
||||||
import { SystemEvent } from '@/types/events'
|
|
||||||
import { getTools } from '@/services/mcp'
|
|
||||||
import { useChat } from '@/hooks/useChat'
|
import { useChat } from '@/hooks/useChat'
|
||||||
import DropdownModelProvider from '@/containers/DropdownModelProvider'
|
import DropdownModelProvider from '@/containers/DropdownModelProvider'
|
||||||
import { ModelLoader } from '@/containers/loaders/ModelLoader'
|
import { ModelLoader } from '@/containers/loaders/ModelLoader'
|
||||||
@ -46,8 +42,7 @@ const ChatInput = ({
|
|||||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||||
const [isFocused, setIsFocused] = useState(false)
|
const [isFocused, setIsFocused] = useState(false)
|
||||||
const [rows, setRows] = useState(1)
|
const [rows, setRows] = useState(1)
|
||||||
const { streamingContent, updateTools, abortControllers, loadingModel } =
|
const { streamingContent, abortControllers, loadingModel } = useAppState()
|
||||||
useAppState()
|
|
||||||
const { prompt, setPrompt } = usePrompt()
|
const { prompt, setPrompt } = usePrompt()
|
||||||
const { currentThreadId } = useThreads()
|
const { currentThreadId } = useThreads()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
@ -102,22 +97,6 @@ const ChatInput = ({
|
|||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
function setTools() {
|
|
||||||
getTools().then((data: MCPTool[]) => {
|
|
||||||
updateTools(data)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
setTools()
|
|
||||||
|
|
||||||
let unsubscribe = () => {}
|
|
||||||
listen(SystemEvent.MCP_UPDATE, setTools).then((unsub) => {
|
|
||||||
// Unsubscribe from the event when the component unmounts
|
|
||||||
unsubscribe = unsub
|
|
||||||
})
|
|
||||||
return unsubscribe
|
|
||||||
}, [updateTools])
|
|
||||||
|
|
||||||
// Focus when component mounts
|
// Focus when component mounts
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (textareaRef.current) {
|
if (textareaRef.current) {
|
||||||
|
|||||||
@ -132,12 +132,25 @@ export const ThreadContent = memo(
|
|||||||
}, [deleteMessage, getMessages, item, sendMessage])
|
}, [deleteMessage, getMessages, item, sendMessage])
|
||||||
|
|
||||||
const removeMessage = useCallback(() => {
|
const removeMessage = useCallback(() => {
|
||||||
if (item.role === 'assistant' || item.role === 'tool') {
|
if (
|
||||||
const threadMessages = getMessages(item.thread_id)
|
item.index !== undefined &&
|
||||||
|
(item.role === 'assistant' || item.role === 'tool')
|
||||||
|
) {
|
||||||
|
const threadMessages = getMessages(item.thread_id).slice(
|
||||||
|
0,
|
||||||
|
item.index + 1
|
||||||
|
)
|
||||||
let toSendMessage = threadMessages.pop()
|
let toSendMessage = threadMessages.pop()
|
||||||
while (toSendMessage && toSendMessage?.role !== 'user') {
|
while (toSendMessage && toSendMessage?.role !== 'user') {
|
||||||
deleteMessage(toSendMessage.thread_id, toSendMessage.id ?? '')
|
deleteMessage(toSendMessage.thread_id, toSendMessage.id ?? '')
|
||||||
toSendMessage = threadMessages.pop()
|
toSendMessage = threadMessages.pop()
|
||||||
|
// Stop deletion when encountering an assistant message that isn’t a tool call
|
||||||
|
if (
|
||||||
|
toSendMessage &&
|
||||||
|
toSendMessage.role === 'assistant' &&
|
||||||
|
!('tool_calls' in (toSendMessage.metadata ?? {}))
|
||||||
|
)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
deleteMessage(item.thread_id, item.id)
|
deleteMessage(item.thread_id, item.id)
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useMemo } from 'react'
|
import { useCallback, useEffect, useMemo } from 'react'
|
||||||
import { usePrompt } from './usePrompt'
|
import { usePrompt } from './usePrompt'
|
||||||
import { useModelProvider } from './useModelProvider'
|
import { useModelProvider } from './useModelProvider'
|
||||||
import { useThreads } from './useThreads'
|
import { useThreads } from './useThreads'
|
||||||
@ -21,18 +21,28 @@ import { CompletionMessagesBuilder } from '@/lib/messages'
|
|||||||
import { ChatCompletionMessageToolCall } from 'openai/resources'
|
import { ChatCompletionMessageToolCall } from 'openai/resources'
|
||||||
import { useAssistant } from './useAssistant'
|
import { useAssistant } from './useAssistant'
|
||||||
import { toast } from 'sonner'
|
import { toast } from 'sonner'
|
||||||
|
import { getTools } from '@/services/mcp'
|
||||||
|
import { MCPTool } from '@/types/completion'
|
||||||
|
import { listen } from '@tauri-apps/api/event'
|
||||||
|
import { SystemEvent } from '@/types/events'
|
||||||
|
|
||||||
export const useChat = () => {
|
export const useChat = () => {
|
||||||
const { prompt, setPrompt } = usePrompt()
|
const { prompt, setPrompt } = usePrompt()
|
||||||
const { tools, updateTokenSpeed, resetTokenSpeed } = useAppState()
|
const {
|
||||||
|
tools,
|
||||||
|
updateTokenSpeed,
|
||||||
|
resetTokenSpeed,
|
||||||
|
updateTools,
|
||||||
|
updateStreamingContent,
|
||||||
|
updateLoadingModel,
|
||||||
|
setAbortController,
|
||||||
|
} = useAppState()
|
||||||
const { currentAssistant } = useAssistant()
|
const { currentAssistant } = useAssistant()
|
||||||
|
|
||||||
const { getProviderByName, selectedModel, selectedProvider } =
|
const { getProviderByName, selectedModel, selectedProvider } =
|
||||||
useModelProvider()
|
useModelProvider()
|
||||||
|
|
||||||
const { getCurrentThread: retrieveThread, createThread } = useThreads()
|
const { getCurrentThread: retrieveThread, createThread } = useThreads()
|
||||||
const { updateStreamingContent, updateLoadingModel, setAbortController } =
|
|
||||||
useAppState()
|
|
||||||
const { getMessages, addMessage } = useMessages()
|
const { getMessages, addMessage } = useMessages()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
@ -40,6 +50,22 @@ export const useChat = () => {
|
|||||||
return getProviderByName(selectedProvider)
|
return getProviderByName(selectedProvider)
|
||||||
}, [selectedProvider, getProviderByName])
|
}, [selectedProvider, getProviderByName])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
function setTools() {
|
||||||
|
getTools().then((data: MCPTool[]) => {
|
||||||
|
updateTools(data)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setTools()
|
||||||
|
|
||||||
|
let unsubscribe = () => {}
|
||||||
|
listen(SystemEvent.MCP_UPDATE, setTools).then((unsub) => {
|
||||||
|
// Unsubscribe from the event when the component unmounts
|
||||||
|
unsubscribe = unsub
|
||||||
|
})
|
||||||
|
return unsubscribe
|
||||||
|
}, [updateTools])
|
||||||
|
|
||||||
const getCurrentThread = useCallback(async () => {
|
const getCurrentThread = useCallback(async () => {
|
||||||
let currentThread = retrieveThread()
|
let currentThread = retrieveThread()
|
||||||
if (!currentThread) {
|
if (!currentThread) {
|
||||||
|
|||||||
@ -199,7 +199,11 @@ function ThreadDetail() {
|
|||||||
showAssistant={
|
showAssistant={
|
||||||
item.role === 'assistant' &&
|
item.role === 'assistant' &&
|
||||||
(index === 0 ||
|
(index === 0 ||
|
||||||
messages[index - 1].role !== 'assistant')
|
messages[index - 1]?.role !== 'assistant' ||
|
||||||
|
!(
|
||||||
|
messages[index - 1]?.metadata &&
|
||||||
|
'tool_calls' in (messages[index - 1].metadata ?? {})
|
||||||
|
))
|
||||||
}
|
}
|
||||||
index={index}
|
index={index}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user