import {ClearOutlined, UserOutlined} from '@ant-design/icons' import {Bubble, Sender, useXAgent, useXChat, Welcome} from '@ant-design/x' import {fetchEventSource} from '@echofly/fetch-event-source' import {useUnmount} from 'ahooks' import {Button, Collapse, Flex, Typography} from 'antd' import {isStrBlank, trim} from 'licia' import {useRef, useState} from 'react' import styled from 'styled-components' import {commonInfo} from '../../util/amis.tsx' import MarkdownRender from '../../util/Markdown.tsx' const ConversationDiv = styled.div` height: calc(100vh - 76px); display: flex; flex-direction: column; padding: 10px; .conversation-welcome { flex: 1; width: 70%; margin: 30px auto 30px; } .conversation-list { flex: 1; margin-bottom: 30px; padding-left: 30px; padding-right: 30px; } .conversation-sender { height: 100px; padding-left: 30px; padding-right: 30px; } ` type ChatMessage = { role: string, content?: string, reason?: string } function Conversation() { const abortController = useRef(null) const [input, setInput] = useState('') useUnmount(() => { console.log('Page Unmount') abortController.current?.abort() }) const [agent] = useXAgent({ request: async (info, callbacks) => { await fetchEventSource(`${commonInfo.baseAiUrl}/chat/async`, { method: 'POST', headers: commonInfo.authorizationHeaders, body: JSON.stringify(info.messages), signal: abortController.current?.signal, onmessage: ev => { callbacks.onUpdate({ id: ev.id, event: 'delta', data: ev.data, }) }, onclose: () => callbacks.onSuccess([]), onerror: error => callbacks.onError(error), }) }, }) const {onRequest, messages, setMessages} = useXChat({ agent, transformMessage: ({originMessage, chunk}) => { let content = '', reason = '' try { if (chunk?.data) { let map = JSON.parse(chunk.data) if (map['content']) content = map['content'] if (map['reason']) reason = map['reason'] } } catch (error) { console.error(error) } return { role: 'assistant', content: (originMessage?.content || '') + content, reason: (originMessage?.reason || '') + reason, } }, resolveAbortController: controller => { abortController.current = controller }, }) return ( {messages.length > 0 ? (, style: { background: 'transparent', }, }, messageRender: item => { let content = '', reason = '' if (!isStrBlank(item['reason'])) { reason = trim(item['reason']) } content = trim(item['content']) return (
{isStrBlank(reason) ? : ), }, ]} />}
) }, }, user: { placement: 'end', avatar: { icon: , }, messageRender: item => { return ( {trim(item['content'])} ) }, }, }} items={messages.map(({id, message}) => { return { key: id, role: message.role, content: message, } })} />) : (
} title="你好,我是基于大模型深度思考技术构建的 AI 运营助手" description="我可以帮你查询、检索Hudi 服务的运行情况,分析、处理 Hudi 服务的运营故障,输出、解读 Hudi 系统整体运营报告" />
)}
{ onRequest({ message: { role: 'user', content: message, }, stream: true, }) setInput('') }} onCancel={() => abortController.current?.abort()} footer={({components}) => { const {SendButton, LoadingButton} = components return ( {agent.isRequesting() ? ( ) : ( )} ) }} actions={false} />
) } export default Conversation