| | |
| | | v-if="item.content?.type === AnswerType.Text || item.content?.type === AnswerType.Knowledge" |
| | | > |
| | | <i |
| | | class="p-2 ywicon icon-copy cursor-pointer hover:text-[#0284ff] hover:!text-[18px]" |
| | | class="p-2 ywifont ywicon-copy cursor-pointer hover:text-[#0284ff] hover:!text-[18px]" |
| | | @click="copyClick(item)" |
| | | /> |
| | | </div> |
| | |
| | | <div class="flex items-center justify-center size-[15px]"> |
| | | <i |
| | | :class="{ 'text-[#0284ff]': item.state === AnswerState.Like }" |
| | | class="p-2 ywicon icon-dianzan cursor-pointer hover:text-[#0284ff] font-medium hover:!text-[18px]" |
| | | class="p-2 ywifont ywicon-dianzan cursor-pointer hover:text-[#0284ff] font-medium hover:!text-[18px]" |
| | | @click="likeClick(item)" |
| | | /> |
| | | </div> |
| | | <div class="flex items-center justify-center size-[15px]"> |
| | | <i |
| | | :class="{ 'text-[#0284ff]': item.state === AnswerState.Unlike }" |
| | | class="p-2 ywicon icon-buzan cursor-pointer hover:text-[#0284ff] !text-[13px] hover:!text-[15px]" |
| | | class="p-2 ywifont ywicon-buzan cursor-pointer hover:text-[#0284ff] !text-[13px] hover:!text-[15px]" |
| | | @click="unLikeClick(item)" |
| | | /> |
| | | </div> |
| | |
| | | |
| | | <div class="flex items-center justify-center size-[15px] relative"> |
| | | <i |
| | | class="p-2 ywicon icon-wentifankui cursor-pointer hover:text-[#0284ff] !text-[13px] hover:!text-[15px]" |
| | | class="p-2 ywifont ywicon-wentifankui cursor-pointer hover:text-[#0284ff] !text-[13px] hover:!text-[15px]" |
| | | @click=" |
| | | ($event) => |
| | | feedbackClick( |
| | |
| | | </div> |
| | | </div> |
| | | |
| | | <Loding v-if="isTalking && index === messageList.length - 1" class="w-fit" :process="process" /> |
| | | <Loding v-if="isTalking && index === computedMessageList.length - 1" class="w-fit" :process="process" /> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | }; |
| | | |
| | | const { clearQueryProcess, process, processId, queryProcess } = useQueryProcess(); |
| | | const DEFAULT_SECTION_A_ID = 'knowledge_base'; |
| | | |
| | | let questionRes = null; |
| | | |
| | | let finalCalcSectionAId = null; |
| | | const questionAi = async (text) => { |
| | | if (!currentSectionId) { |
| | | ElMessage.warning('发送失败,未确定应用场景!'); |
| | | } |
| | | processId.value = uuidv4(); |
| | | let judgeParams = null; |
| | | if (!preQuestion.value) { |
| | |
| | | // prev_question: lastQuestion, |
| | | // } |
| | | // : {}; |
| | | // 正常回答暂时不采用 |
| | | // 正常回答暂时不采用 |
| | | judgeParams = {}; |
| | | } else { |
| | | judgeParams = { |
| | | prev_question: preQuestion.value, |
| | | }; |
| | | } |
| | | |
| | | let currentSectionAId = ''; |
| | | if (activeSectionAId.value) { |
| | | currentSectionAId = activeSectionAId.value; |
| | | activeSectionAId.value = ''; |
| | | } else { |
| | | const lastSectionAItem = _.findLast( |
| | | computedMessageList.value as any, |
| | | (item) => item.role === RoleEnum.assistant && !!item.sectionAId |
| | | ); |
| | | currentSectionAId = lastSectionAItem?.sectionAId ?? DEFAULT_SECTION_A_ID; |
| | | } |
| | | finalCalcSectionAId = currentSectionAId; |
| | | |
| | | const params = { |
| | | process_id: processId.value, |
| | | question: text, |
| | | // FIXME: 暂时这样 |
| | | section_a_id: currentSectionId, |
| | | section_a_id: currentSectionAId, |
| | | history_group_id: currentRouteId, |
| | | raw_mode: roomConfig.value?.[currentRouteId]?.isAnswerByLLM ?? false, |
| | | ...judgeParams, |
| | |
| | | |
| | | if (currentSampleId) { |
| | | params.sample_id = currentSampleId; |
| | | currentSampleId = ''; |
| | | } |
| | | |
| | | if (currentLLMId) { |
| | | params.llm_id = currentLLMId; |
| | | } |
| | | // if (currentLLMId) { |
| | | // params.llm_id = currentLLMId; |
| | | // } |
| | | clearQueryProcess(); |
| | | queryProcess(); |
| | | const res = await QuestionAi(params).finally(() => { |
| | |
| | | values: '', |
| | | }); |
| | | |
| | | let currentSectionId = null; |
| | | let currentSampleId = null; |
| | | let currentSampleId = ''; |
| | | |
| | | let currentLLMId = null; |
| | | |
| | |
| | | |
| | | if (activeLLMId.value) { |
| | | currentLLMId = activeLLMId.value; |
| | | } |
| | | |
| | | if (activeSectionAId.value) { |
| | | currentSectionId = activeSectionAId.value; |
| | | } |
| | | } |
| | | let resMsgContent: ChatContent = null; |
| | |
| | | userItem.historyId = questionRes.history_id; |
| | | userItem.content.values = questionRes?.question ?? userItem.content.values; |
| | | assistantItem.historyId = questionRes.history_id; |
| | | assistantItem.sectionAId = finalCalcSectionAId; |
| | | appendLastMessageContent(resMsgContent); |
| | | } catch (error: any) { |
| | | // appendLastMessageContent({ |
| | |
| | | } |
| | | }; |
| | | |
| | | // 一次性加载最近条数限制 |
| | | const LOAD_CHAT_LIMIT = 10; |
| | | |
| | | // 所有用户提问历史记录 |
| | | let userMsgHistory = []; |
| | | // 下次加载用户提问索引位置 |
| | | let nextUserMsgEndIndex = 0; |
| | | |
| | | onMounted(async () => { |
| | | const res = await QueryHistoryDetail({ |
| | | history_group_id: currentRouteId, |
| | | }); |
| | | |
| | | messageList.value = (res.details ?? []).map((item) => { |
| | | userMsgHistory = res.details ?? []; |
| | | nextUserMsgEndIndex = userMsgHistory.length; |
| | | // 截取倒数 LOAD_CHAT_LIMIT 条用户消息 |
| | | const currentUserMsgList = userMsgHistory.slice(nextUserMsgEndIndex - LOAD_CHAT_LIMIT, nextUserMsgEndIndex); |
| | | messageList.value = currentUserMsgList.map((item) => { |
| | | return { |
| | | historyId: item.history_id, |
| | | role: RoleEnum.user, |
| | |
| | | }, |
| | | } as ChatMessage; |
| | | }); |
| | | currentSectionId = res?.details?.[0]?.section_a_id; |
| | | currentSampleId = res?.details?.[0]?.sample_id; |
| | | const resList = await Promise.all((res.details ?? []).map((item) => getAnswerById(item.history_id))); |
| | | let i = 0; |
| | | resList.map((item, index) => { |
| | | const insertIndex = index + 1 + i; |
| | | const userMsg = messageList.value[insertIndex - 1]; |
| | | userMsg.content.values = item?.answer?.question ??userMsg.content.values; |
| | | messageList.value.splice( |
| | | insertIndex, |
| | | 0, |
| | | item.answer === null |
| | | ? null |
| | | : { |
| | | historyId: item.answer?.history_id, |
| | | role: RoleEnum.assistant, |
| | | content: parseContent(item.answer), |
| | | state: item.answer_state, |
| | | } |
| | | ); |
| | | i++; |
| | | const sectionAIdMap = new Map(); |
| | | |
| | | // 获取结果插入到用户提问之后 |
| | | currentUserMsgList.map((item) => { |
| | | sectionAIdMap.set(item.history_id, item.section_a_id); |
| | | getAnswerById(item.history_id).then((aiRobot) => { |
| | | // 用户提问索引 |
| | | const userMsgIndex = messageList.value.findIndex((subItem) => subItem.historyId === item.history_id); |
| | | const userMsg = messageList.value[userMsgIndex]; |
| | | // values 取回答之后最终的 question |
| | | userMsg.content.values = aiRobot.answer?.question ?? userMsg.content.values; |
| | | messageList.value.splice( |
| | | userMsgIndex + 1, |
| | | 0, |
| | | aiRobot.answer === null |
| | | ? null |
| | | : { |
| | | historyId: aiRobot.answer?.history_id, |
| | | role: RoleEnum.assistant, |
| | | content: parseContent(aiRobot.answer), |
| | | state: aiRobot.answer_state, |
| | | sectionAId: sectionAIdMap.get(aiRobot.answer.history_id), |
| | | } |
| | | ); |
| | | }); |
| | | }); |
| | | |
| | | if (messageList.value.length === 0) { |