feat: switch to chat messages before regenerated (#11301)
Co-authored-by: zuodongxu <192560071+zuodongxu@users.noreply.github.com>
This commit is contained in:
parent
b09c39c8dc
commit
c0d0c63592
15 changed files with 576 additions and 579 deletions
|
|
@ -3,10 +3,11 @@ import Chat from '../chat'
|
|||
import type {
|
||||
ChatConfig,
|
||||
ChatItem,
|
||||
ChatItemInTree,
|
||||
OnSend,
|
||||
} from '../types'
|
||||
import { useChat } from '../chat/hooks'
|
||||
import { getLastAnswer } from '../utils'
|
||||
import { getLastAnswer, isValidGeneratedAnswer } from '../utils'
|
||||
import { useChatWithHistoryContext } from './context'
|
||||
import Header from './header'
|
||||
import ConfigPanel from './config-panel'
|
||||
|
|
@ -20,7 +21,7 @@ import AnswerIcon from '@/app/components/base/answer-icon'
|
|||
const ChatWrapper = () => {
|
||||
const {
|
||||
appParams,
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
inputsForms,
|
||||
|
|
@ -50,8 +51,7 @@ const ChatWrapper = () => {
|
|||
}, [appParams, currentConversationItem?.introduction, currentConversationId])
|
||||
const {
|
||||
chatList,
|
||||
chatListRef,
|
||||
handleUpdateChatList,
|
||||
setTargetMessageId,
|
||||
handleSend,
|
||||
handleStop,
|
||||
isResponding,
|
||||
|
|
@ -62,7 +62,7 @@ const ChatWrapper = () => {
|
|||
inputs: (currentConversationId ? currentConversationItem?.inputs : newConversationInputs) as any,
|
||||
inputsForm: inputsForms,
|
||||
},
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
taskId => stopChatMessageResponding('', taskId, isInstalledApp, appId),
|
||||
)
|
||||
|
||||
|
|
@ -72,13 +72,13 @@ const ChatWrapper = () => {
|
|||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
const doSend: OnSend = useCallback((message, files, last_answer) => {
|
||||
const doSend: OnSend = useCallback((message, files, isRegenerate = false, parentAnswer: ChatItem | null = null) => {
|
||||
const data: any = {
|
||||
query: message,
|
||||
files,
|
||||
inputs: currentConversationId ? currentConversationItem?.inputs : newConversationInputs,
|
||||
conversation_id: currentConversationId,
|
||||
parent_message_id: last_answer?.id || getLastAnswer(chatListRef.current)?.id || null,
|
||||
parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
|
||||
}
|
||||
|
||||
handleSend(
|
||||
|
|
@ -91,31 +91,21 @@ const ChatWrapper = () => {
|
|||
},
|
||||
)
|
||||
}, [
|
||||
chatListRef,
|
||||
chatList,
|
||||
handleNewConversationCompleted,
|
||||
handleSend,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
handleSend,
|
||||
newConversationInputs,
|
||||
handleNewConversationCompleted,
|
||||
isInstalledApp,
|
||||
appId,
|
||||
])
|
||||
|
||||
const doRegenerate = useCallback((chatItem: ChatItem) => {
|
||||
const index = chatList.findIndex(item => item.id === chatItem.id)
|
||||
if (index === -1)
|
||||
return
|
||||
|
||||
const prevMessages = chatList.slice(0, index)
|
||||
const question = prevMessages.pop()
|
||||
const lastAnswer = getLastAnswer(prevMessages)
|
||||
|
||||
if (!question)
|
||||
return
|
||||
|
||||
handleUpdateChatList(prevMessages)
|
||||
doSend(question.content, question.message_files, lastAnswer)
|
||||
}, [chatList, handleUpdateChatList, doSend])
|
||||
const doRegenerate = useCallback((chatItem: ChatItemInTree) => {
|
||||
const question = chatList.find(item => item.id === chatItem.parentMessageId)!
|
||||
const parentAnswer = chatList.find(item => item.id === question.parentMessageId)
|
||||
doSend(question.content, question.message_files, true, isValidGeneratedAnswer(parentAnswer) ? parentAnswer : null)
|
||||
}, [chatList, doSend])
|
||||
|
||||
const chatNode = useMemo(() => {
|
||||
if (inputsForms.length) {
|
||||
|
|
@ -187,6 +177,7 @@ const ChatWrapper = () => {
|
|||
answerIcon={answerIcon}
|
||||
hideProcessDetail
|
||||
themeBuilder={themeBuilder}
|
||||
switchSibling={siblingMessageId => setTargetMessageId(siblingMessageId)}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import { createContext, useContext } from 'use-context-selector'
|
|||
import type {
|
||||
Callback,
|
||||
ChatConfig,
|
||||
ChatItem,
|
||||
ChatItemInTree,
|
||||
Feedback,
|
||||
} from '../types'
|
||||
import type { ThemeBuilder } from '../embedded-chatbot/theme/theme-context'
|
||||
|
|
@ -25,7 +25,7 @@ export type ChatWithHistoryContextValue = {
|
|||
appChatListDataLoading?: boolean
|
||||
currentConversationId: string
|
||||
currentConversationItem?: ConversationItem
|
||||
appPrevChatList: ChatItem[]
|
||||
appPrevChatTree: ChatItemInTree[]
|
||||
pinnedConversationList: AppConversationData['data']
|
||||
conversationList: AppConversationData['data']
|
||||
showConfigPanelBeforeChat: boolean
|
||||
|
|
@ -53,7 +53,7 @@ export type ChatWithHistoryContextValue = {
|
|||
|
||||
export const ChatWithHistoryContext = createContext<ChatWithHistoryContextValue>({
|
||||
currentConversationId: '',
|
||||
appPrevChatList: [],
|
||||
appPrevChatTree: [],
|
||||
pinnedConversationList: [],
|
||||
conversationList: [],
|
||||
showConfigPanelBeforeChat: false,
|
||||
|
|
|
|||
|
|
@ -12,10 +12,13 @@ import produce from 'immer'
|
|||
import type {
|
||||
Callback,
|
||||
ChatConfig,
|
||||
ChatItem,
|
||||
Feedback,
|
||||
} from '../types'
|
||||
import { CONVERSATION_ID_INFO } from '../constants'
|
||||
import { getPrevChatList } from '../utils'
|
||||
import { buildChatItemTree } from '../utils'
|
||||
import { addFileInfos, sortAgentSorts } from '../../../tools/utils'
|
||||
import { getProcessedFilesFromResponse } from '@/app/components/base/file-uploader/utils'
|
||||
import {
|
||||
delConversation,
|
||||
fetchAppInfo,
|
||||
|
|
@ -40,6 +43,32 @@ import { useAppFavicon } from '@/hooks/use-app-favicon'
|
|||
import { InputVarType } from '@/app/components/workflow/types'
|
||||
import { TransferMethod } from '@/types/app'
|
||||
|
||||
function getFormattedChatList(messages: any[]) {
|
||||
const newChatList: ChatItem[] = []
|
||||
messages.forEach((item) => {
|
||||
const questionFiles = item.message_files?.filter((file: any) => file.belongs_to === 'user') || []
|
||||
newChatList.push({
|
||||
id: `question-${item.id}`,
|
||||
content: item.query,
|
||||
isAnswer: false,
|
||||
message_files: getProcessedFilesFromResponse(questionFiles.map((item: any) => ({ ...item, related_id: item.id }))),
|
||||
parentMessageId: item.parent_message_id || undefined,
|
||||
})
|
||||
const answerFiles = item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || []
|
||||
newChatList.push({
|
||||
id: item.id,
|
||||
content: item.answer,
|
||||
agent_thoughts: addFileInfos(item.agent_thoughts ? sortAgentSorts(item.agent_thoughts) : item.agent_thoughts, item.message_files),
|
||||
feedback: item.feedback,
|
||||
isAnswer: true,
|
||||
citation: item.retriever_resources,
|
||||
message_files: getProcessedFilesFromResponse(answerFiles.map((item: any) => ({ ...item, related_id: item.id }))),
|
||||
parentMessageId: `question-${item.id}`,
|
||||
})
|
||||
})
|
||||
return newChatList
|
||||
}
|
||||
|
||||
export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
||||
const isInstalledApp = useMemo(() => !!installedAppInfo, [installedAppInfo])
|
||||
const { data: appInfo, isLoading: appInfoLoading, error: appInfoError } = useSWR(installedAppInfo ? null : 'appInfo', fetchAppInfo)
|
||||
|
|
@ -109,9 +138,9 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
|||
const { data: appConversationData, isLoading: appConversationDataLoading, mutate: mutateAppConversationData } = useSWR(['appConversationData', isInstalledApp, appId, false], () => fetchConversations(isInstalledApp, appId, undefined, false, 100))
|
||||
const { data: appChatListData, isLoading: appChatListDataLoading } = useSWR(chatShouldReloadKey ? ['appChatList', chatShouldReloadKey, isInstalledApp, appId] : null, () => fetchChatList(chatShouldReloadKey, isInstalledApp, appId))
|
||||
|
||||
const appPrevChatList = useMemo(
|
||||
const appPrevChatTree = useMemo(
|
||||
() => (currentConversationId && appChatListData?.data.length)
|
||||
? getPrevChatList(appChatListData.data)
|
||||
? buildChatItemTree(getFormattedChatList(appChatListData.data))
|
||||
: [],
|
||||
[appChatListData, currentConversationId],
|
||||
)
|
||||
|
|
@ -403,7 +432,7 @@ export const useChatWithHistory = (installedAppInfo?: InstalledApp) => {
|
|||
appConversationDataLoading,
|
||||
appChatListData,
|
||||
appChatListDataLoading,
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
pinnedConversationList,
|
||||
conversationList,
|
||||
showConfigPanelBeforeChat,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
|||
appInfoError,
|
||||
appData,
|
||||
appInfoLoading,
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
showConfigPanelBeforeChat,
|
||||
appChatListDataLoading,
|
||||
chatShouldReloadKey,
|
||||
|
|
@ -38,7 +38,7 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
|||
themeBuilder,
|
||||
} = useChatWithHistoryContext()
|
||||
|
||||
const chatReady = (!showConfigPanelBeforeChat || !!appPrevChatList.length)
|
||||
const chatReady = (!showConfigPanelBeforeChat || !!appPrevChatTree.length)
|
||||
const customConfig = appData?.custom_config
|
||||
const site = appData?.site
|
||||
|
||||
|
|
@ -76,9 +76,9 @@ const ChatWithHistory: FC<ChatWithHistoryProps> = ({
|
|||
<HeaderInMobile />
|
||||
)
|
||||
}
|
||||
<div className={`grow overflow-hidden ${showConfigPanelBeforeChat && !appPrevChatList.length && 'flex items-center justify-center'}`}>
|
||||
<div className={`grow overflow-hidden ${showConfigPanelBeforeChat && !appPrevChatTree.length && 'flex items-center justify-center'}`}>
|
||||
{
|
||||
showConfigPanelBeforeChat && !appChatListDataLoading && !appPrevChatList.length && (
|
||||
showConfigPanelBeforeChat && !appChatListDataLoading && !appPrevChatTree.length && (
|
||||
<div className={`flex w-full items-center justify-center h-full ${isMobile && 'px-4'}`}>
|
||||
<ConfigPanel />
|
||||
</div>
|
||||
|
|
@ -120,7 +120,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
|||
appChatListDataLoading,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
pinnedConversationList,
|
||||
conversationList,
|
||||
showConfigPanelBeforeChat,
|
||||
|
|
@ -154,7 +154,7 @@ const ChatWithHistoryWrap: FC<ChatWithHistoryWrapProps> = ({
|
|||
appChatListDataLoading,
|
||||
currentConversationId,
|
||||
currentConversationItem,
|
||||
appPrevChatList,
|
||||
appPrevChatTree,
|
||||
pinnedConversationList,
|
||||
conversationList,
|
||||
showConfigPanelBeforeChat,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue