Skip to content

Commit

Permalink
feat: chatflow log supports viewing thread messages
Browse files Browse the repository at this point in the history
  • Loading branch information
xuzuodong committed Sep 13, 2024
1 parent 31276c5 commit fc5aff3
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 32 deletions.
2 changes: 1 addition & 1 deletion web/app/components/app/log/list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ function DetailPanel<T extends ChatConversationFullDetailResponse | CompletionCo
{/* Put the scroll bar always on the bottom */}
<InfiniteScroll
scrollableTarget="scrollableDiv"
dataLength={allChatItems.length}
dataLength={threadChatItems.length}
next={fetchData}
hasMore={hasMore}
loader={<div className='text-center text-gray-400 text-xs'>{t('appLog.detail.loading')}...</div>}
Expand Down
76 changes: 45 additions & 31 deletions web/app/components/workflow/panel/chat-record/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
memo,
useCallback,
useEffect,
useMemo,
useState,
} from 'react'
import { RiCloseLine } from '@remixicon/react'
Expand All @@ -13,61 +12,75 @@ import {
import { useWorkflowRun } from '../../hooks'
import UserInput from './user-input'
import Chat from '@/app/components/base/chat/chat'
import type { ChatItem } from '@/app/components/base/chat/types'
import type { ChatItem, ChatItemInTree } from '@/app/components/base/chat/types'
import { fetchConversationMessages } from '@/service/debug'
import { useStore as useAppStore } from '@/app/components/app/store'
import Loading from '@/app/components/base/loading'
import type { IChatItem } from '@/app/components/base/chat/chat/type'
import { buildChatItemTree, getThreadMessages } from '@/app/components/base/chat/utils'

const getFormattedChatList = (messages: any[]) => {
const res: ChatItem[] = []
messages.forEach((item: any) => {
res.push({
id: `question-${item.id}`,
content: item.query,
isAnswer: false,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
parentMessageId: item.parent_message_id || undefined,
})
res.push({
id: item.id,
content: item.answer,
feedback: item.feedback,
isAnswer: true,
citation: item.metadata?.retriever_resources,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
workflow_run_id: item.workflow_run_id,
parentMessageId: `question-${item.id}`,
})
})
return res
}

const ChatRecord = () => {
const [fetched, setFetched] = useState(false)
const [chatList, setChatList] = useState([])
const [chatItemTree, setChatItemTree] = useState<ChatItemInTree[]>([])
const [threadChatItems, setThreadChatItems] = useState<IChatItem[]>([])
const appDetail = useAppStore(s => s.appDetail)
const workflowStore = useWorkflowStore()
const { handleLoadBackupDraft } = useWorkflowRun()
const historyWorkflowData = useStore(s => s.historyWorkflowData)
const currentConversationID = historyWorkflowData?.conversation_id

const chatMessageList = useMemo(() => {
const res: ChatItem[] = []
if (chatList.length) {
chatList.forEach((item: any) => {
res.push({
id: `question-${item.id}`,
content: item.query,
isAnswer: false,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'user') || [],
})
res.push({
id: item.id,
content: item.answer,
feedback: item.feedback,
isAnswer: true,
citation: item.metadata?.retriever_resources,
message_files: item.message_files?.filter((file: any) => file.belongs_to === 'assistant') || [],
workflow_run_id: item.workflow_run_id,
})
})
}
return res
}, [chatList])

const handleFetchConversationMessages = useCallback(async () => {
if (appDetail && currentConversationID) {
try {
setFetched(false)
const res = await fetchConversationMessages(appDetail.id, currentConversationID)
setFetched(true)
setChatList((res as any).data)

const newAllChatItems = getFormattedChatList((res as any).data)

const tree = buildChatItemTree(newAllChatItems)
setChatItemTree(tree)
setThreadChatItems(getThreadMessages(tree, newAllChatItems.at(-1)?.id))
}
catch (e) {

}
finally {
setFetched(true)
}
}
}, [appDetail, currentConversationID])

useEffect(() => {
handleFetchConversationMessages()
}, [currentConversationID, appDetail, handleFetchConversationMessages])

const switchSibling = useCallback((siblingMessageId: string) => {
setThreadChatItems(getThreadMessages(chatItemTree, siblingMessageId))
}, [chatItemTree])

return (
<div
className={`
Expand Down Expand Up @@ -101,7 +114,7 @@ const ChatRecord = () => {
config={{
supportCitationHitInfo: true,
} as any}
chatList={chatMessageList}
chatList={threadChatItems}
chatContainerClassName='px-4'
chatContainerInnerClassName='pt-6 w-full max-w-full mx-auto'
chatFooterClassName='px-4 rounded-b-2xl'
Expand All @@ -110,6 +123,7 @@ const ChatRecord = () => {
noChatInput
allToolIcons={{}}
showPromptLog
switchSibling={switchSibling}
/>
</div>
</>
Expand Down

0 comments on commit fc5aff3

Please sign in to comment.