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 { 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 DropdownModelProvider from '@/containers/DropdownModelProvider'
|
||||
import { ModelLoader } from '@/containers/loaders/ModelLoader'
|
||||
@ -46,8 +42,7 @@ const ChatInput = ({
|
||||
const textareaRef = useRef<HTMLTextAreaElement>(null)
|
||||
const [isFocused, setIsFocused] = useState(false)
|
||||
const [rows, setRows] = useState(1)
|
||||
const { streamingContent, updateTools, abortControllers, loadingModel } =
|
||||
useAppState()
|
||||
const { streamingContent, abortControllers, loadingModel } = useAppState()
|
||||
const { prompt, setPrompt } = usePrompt()
|
||||
const { currentThreadId } = useThreads()
|
||||
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
|
||||
useEffect(() => {
|
||||
if (textareaRef.current) {
|
||||
|
||||
@ -132,12 +132,25 @@ export const ThreadContent = memo(
|
||||
}, [deleteMessage, getMessages, item, sendMessage])
|
||||
|
||||
const removeMessage = useCallback(() => {
|
||||
if (item.role === 'assistant' || item.role === 'tool') {
|
||||
const threadMessages = getMessages(item.thread_id)
|
||||
if (
|
||||
item.index !== undefined &&
|
||||
(item.role === 'assistant' || item.role === 'tool')
|
||||
) {
|
||||
const threadMessages = getMessages(item.thread_id).slice(
|
||||
0,
|
||||
item.index + 1
|
||||
)
|
||||
let toSendMessage = threadMessages.pop()
|
||||
while (toSendMessage && toSendMessage?.role !== 'user') {
|
||||
deleteMessage(toSendMessage.thread_id, toSendMessage.id ?? '')
|
||||
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 {
|
||||
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 { useModelProvider } from './useModelProvider'
|
||||
import { useThreads } from './useThreads'
|
||||
@ -21,18 +21,28 @@ import { CompletionMessagesBuilder } from '@/lib/messages'
|
||||
import { ChatCompletionMessageToolCall } from 'openai/resources'
|
||||
import { useAssistant } from './useAssistant'
|
||||
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 = () => {
|
||||
const { prompt, setPrompt } = usePrompt()
|
||||
const { tools, updateTokenSpeed, resetTokenSpeed } = useAppState()
|
||||
const {
|
||||
tools,
|
||||
updateTokenSpeed,
|
||||
resetTokenSpeed,
|
||||
updateTools,
|
||||
updateStreamingContent,
|
||||
updateLoadingModel,
|
||||
setAbortController,
|
||||
} = useAppState()
|
||||
const { currentAssistant } = useAssistant()
|
||||
|
||||
const { getProviderByName, selectedModel, selectedProvider } =
|
||||
useModelProvider()
|
||||
|
||||
const { getCurrentThread: retrieveThread, createThread } = useThreads()
|
||||
const { updateStreamingContent, updateLoadingModel, setAbortController } =
|
||||
useAppState()
|
||||
const { getMessages, addMessage } = useMessages()
|
||||
const router = useRouter()
|
||||
|
||||
@ -40,6 +50,22 @@ export const useChat = () => {
|
||||
return getProviderByName(selectedProvider)
|
||||
}, [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 () => {
|
||||
let currentThread = retrieveThread()
|
||||
if (!currentThread) {
|
||||
|
||||
@ -199,7 +199,11 @@ function ThreadDetail() {
|
||||
showAssistant={
|
||||
item.role === 'assistant' &&
|
||||
(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}
|
||||
/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user