import { type FC, type ReactNode, useState, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { Col, Row, App, Skeleton, Space, Select, Flex } from 'antd'
import clsx from 'clsx'
import ConversationEmptyIcon from '@/assets/images/conversation/conversationEmpty.svg'
import AnalysisEmptyIcon from '@/assets/images/conversation/analysisEmpty.png'
import Card from './components/Card'
import { readService, getUserMemoryList } from '@/api/memory'
import Empty from '@/components/Empty'
import Markdown from '@/components/Markdown'
import type { Data } from '@/views/UserMemory/types'
import Chat from '@/components/Chat'
import MemoryFunctionIcon from '@/assets/images/conversation/memoryFunction.svg'
import OnlineIcon from '@/assets/images/conversation/online.svg'
import DeepThinkingIcon from '@/assets/images/conversation/deepThinking.svg'
import ButtonCheckbox from '@/components/ButtonCheckbox'
import DeepThinkingCheckedIcon from '@/assets/images/conversation/deepThinkingChecked.svg'
import OnlineCheckedIcon from '@/assets/images/conversation/onlineChecked.svg'
import MemoryFunctionCheckedIcon from '@/assets/images/conversation/memoryFunctionChecked.svg'
import type { ChatItem } from '@/components/Chat/types'
import dayjs from 'dayjs'
import type { AnyObject } from 'antd/es/_util/type';
const searchSwitchList = [
{
icon: DeepThinkingIcon,
checkedIcon: DeepThinkingCheckedIcon,
value: '0',
label: 'deepThinking' // 深度思考
},
{
icon: MemoryFunctionIcon,
checkedIcon: MemoryFunctionCheckedIcon,
value: '1',
label: 'normalReply' // 普通回复
},
{
icon: OnlineIcon,
checkedIcon: OnlineCheckedIcon,
value: '2',
label: 'quickReply' // 快速回复
},
]
export interface TestParams {
group_id: string;
message: string;
search_switch: string;
history: { role: string; content: string }[];
web_search?: boolean;
memory?: boolean;
conversation_id?: string;
}
interface DataItem {
id: string;
question: string;
type: string;
reason: string;
}
export interface LogItem {
type: string;
title: string;
data?: DataItem[] | AnyObject;
raw_results?: string | AnyObject;
summary?: string;
query?: string;
reason?: string;
result?: string;
original_query: string;
index?: number;
}
const ContentWrapper: FC<{ children: ReactNode }> = ({ children }) => (
{children}
)
const MemoryConversation: FC = () => {
const { t } = useTranslation()
const { message } = App.useApp();
const [userId, setUserId] = useState()
const [loading, setLoading] = useState(false)
const [chatData, setChatData] = useState([])
const [logs, setLogs] = useState([])
const [userList, setUserList] = useState([])
const [search_switch, setSearchSwitch] = useState('0')
const [msg, setMsg] = useState('')
useEffect(() => {
getUserMemoryList().then(res => {
setUserList((res as Data[] || []).map(item => ({
...item,
name: item.end_user?.other_name && item.end_user?.other_name !== '' ? item.end_user?.other_name : item.end_user?.id
})))
})
}, [])
const handleSend = () => {
if(!userId) {
message.warning(t('common.inputPlaceholder', { title: t('memoryConversation.userID') }))
return
}
setChatData(prev => [...prev, { content: msg, created_at: new Date().getTime(), role: 'user' }])
setLoading(true)
readService({
message: msg,
group_id: userId,
search_switch: search_switch,
history: [],
})
.then(res => {
const response = res as { answer: string; intermediate_outputs: LogItem[] }
setChatData(prev => [...prev, { content: response.answer || '-', created_at: new Date().getTime(), role: 'assistant' }])
setLogs(response.intermediate_outputs)
})
.finally(() => {
setLoading(false)
})
}
const handleChange = (value: string) => {
setSearchSwitch(value)
}
return (
<>
}
contentClassName='rb:h-[calc(100vh-362px)]'
data={chatData}
onChange={setMsg}
onSend={handleSend}
loading={loading}
labelFormat={(item) => dayjs(item.created_at).locale('en').format('MMMM D, YYYY [at] h:mm A')}
>
{searchSwitchList.map(item => (
handleChange(item.value)}
>
{t(`memoryConversation.${item.label}`)}
))}
{loading ?
: !logs || logs.length === 0 ?
:
{logs.map((log, logIndex) => (
{log.title}
{log.type === 'problem_split' && Array.isArray(log.data) && log.data.length > 0
?
{log.data.map(vo => (
<>
{vo.id}. {vo.question}
{vo.reason}
>
))}
: log.type === 'problem_extension' && log.data && Object.keys(log.data).length > 0
?
{Object.keys(log.data).map((key: string) => (
<>
{key}
{(log.data as Record)[key].map((item, index) => (
{item}
))}
>
))}
: log.type === 'search_result' && log.raw_results
?
{log.query}
{typeof log.raw_results === 'string'
?
: <>
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string }, index: number) => (
{item.statement}
))}
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string }, index: number) => (
{item.content}
))}
>
}
: log.type === 'retrieval_summary' && log.summary
?
{log.summary}
: log.type === 'verification'
?
{log.query}
{log.reason}
{log.result}
: log.type === 'output_type'
?
{log.query}
{log.summary}
: log.type === 'input_summary' && log.raw_results
?
{log.query}
{log.summary}
{typeof log.raw_results === 'string'
?
: <>
{log.raw_results.reranked_results?.statements.length > 0 && log.raw_results.reranked_results?.statements.map((item: { statement: string; } , index: number) => (
{item.statement}
))}
{log.raw_results.reranked_results?.summaries.length > 0 && log.raw_results.reranked_results?.summaries.map((item: { content: string; }, index: number) => (
{item.content}
))}
>
}
: null
}
))}
}
>
)
}
export default MemoryConversation