import { forwardRef, useImperativeHandle, useState, useRef } from 'react'; import { Button, Form, Input, App, Row, Col } from 'antd'; import { useTranslation } from 'react-i18next'; import clsx from 'clsx' import copy from 'copy-to-clipboard'; import { updatePromptMessages, createPromptSessions } from '@/api/prompt' import { getModelListUrl } from '@/api/models' import type { AiPromptModalRef, AiPromptVariableModalRef, AiPromptForm } from '../types' import RbModal from '@/components/RbModal' import type { Model } from '@/views/ModelManagement/types' import ChatContent from '@/components/Chat/ChatContent' import Empty from '@/components/Empty' import ChatSendIcon from '@/assets/images/application/chatSend.svg' import ConversationEmptyIcon from '@/assets/images/conversation/conversationEmpty.svg' import type { ChatItem } from '@/components/Chat/types' import CustomSelect from '@/components/CustomSelect' import AiPromptVariableModal from './AiPromptVariableModal' import { type SSEMessage } from '@/utils/stream' import Editor from './Editor' interface AiPromptModalProps { refresh: (value: string) => void; defaultModel: Model | null; } const AiPromptModal = forwardRef(({ refresh, defaultModel, }, ref) => { const { t } = useTranslation(); const { message } = App.useApp() const [visible, setVisible] = useState(false); const [loading, setLoading] = useState(false) const [form] = Form.useForm() const [chatList, setChatList] = useState([]) const [variables, setVariables] = useState([]) const [promptSession, setPromptSession] = useState(null) const aiPromptVariableModalRef = useRef(null) const editorRef = useRef(null) const currentPromptValueRef = useRef('') const values = Form.useWatch([], form) // 封装取消方法,添加关闭弹窗逻辑 const handleClose = () => { setVisible(false); setLoading(false) setChatList([]) setVariables([]) form.setFieldsValue({ message: undefined, current_prompt: undefined, }) }; const handleOpen = () => { createPromptSessions() .then(res => { const response = res as { id: string } setPromptSession(response.id) if (!values.model_id && defaultModel?.id) { form.setFieldValue('model_id', defaultModel?.id) } setVisible(true); }) }; const handleSend = () => { if (!promptSession) return if (!values.model_id) { message.warning(t('common.selectPlaceholder', { title: t('application.model') })) return } if (!values.message) { message.warning(t('application.promptChatPlaceholder')) return } const messageContent = values.message setLoading(true) setChatList(prev => { return [...prev, { role: 'user', content: messageContent}] }) form.setFieldsValue({ message: undefined, current_prompt: undefined }) const handleStreamMessage = (data: SSEMessage[]) => { data.map(item => { const { content, desc, variables } = item.data as { content: string; desc: string; variables: string[] }; switch (item.event) { case 'start': currentPromptValueRef.current = '' if (editorRef.current?.clear) { editorRef.current.clear(); } break; case 'message': if (content) { currentPromptValueRef.current += content; if (editorRef.current?.appendText) { editorRef.current.appendText(content); editorRef.current.scrollToBottom(); } else { form.setFieldsValue({ current_prompt: currentPromptValueRef.current }) } } if (desc) { setChatList(prev => { return [...prev, { role: 'assistant', content: desc }] }) } if (variables) { setVariables(variables) } break; case 'end': setLoading(false) // 流结束时同步表单值 form.setFieldsValue({ current_prompt: currentPromptValueRef.current }) break } }) }; updatePromptMessages(promptSession, values, handleStreamMessage) // .then(res => { // const response = res as { prompt: string; desc: string; variables: string[] } // form.setFieldsValue({ current_prompt: response.prompt }) // setChatList(prev => { // return [...prev, { role: 'assistant', content: response.desc }] // }) // setVariables(response.variables) // }) .finally(() => { setLoading(false) }) } const handleCopy = () => { if (!values.current_prompt || values?.current_prompt?.trim() === '') return copy(values.current_prompt) message.success(t('common.copySuccess')) } const handleAdd = () => { aiPromptVariableModalRef.current?.handleOpen() } const handleVariableApply = (value: string) => { if (editorRef.current?.insertText) { editorRef.current.insertText(value) } else { form.setFieldValue('current_prompt', (values.current_prompt || '') + value) } } const handleApply = () => { if (!values.current_prompt) { return } refresh(values.current_prompt) handleClose() } // 暴露给父组件的方法 useImperativeHandle(ref, () => ({ handleOpen, })); console.log(values) return (
} data={chatList || []} streamLoading={false} labelPosition="top" labelFormat={(item) => item.role === 'user' ? t('application.you') : t('application.ai')} />
form.setFieldValue('current_prompt', value)} />
); }); export default AiPromptModal;