From 1da0bc255179f25b5227bec27833cf486cb6cb90 Mon Sep 17 00:00:00 2001 From: yinbangzhong <zhongbangyin@126.com> Date: 星期二, 10 九月 2024 19:41:40 +0800 Subject: [PATCH] agent会话 --- src/views/dmx/IntelligentAgent/components/agentConfig.vue | 4 src/api/agentSession.ts | 8 + yarn.lock | 2 src/views/dmx/knowledgeLib/components/excel.vue | 3 src/views/sessionManager/components/agentSession.vue | 90 ++++++-------- src/views/sessionManager/index.vue | 140 ++++++----------------- src/views/sessionManager/components/updataFile.vue | 34 ----- src/views/dmx/knowledgeLib/components/txt.vue | 33 ++++- src/main.ts | 1 9 files changed, 121 insertions(+), 194 deletions(-) diff --git a/src/api/agentSession.ts b/src/api/agentSession.ts index fad49ac..ef8e05a 100644 --- a/src/api/agentSession.ts +++ b/src/api/agentSession.ts @@ -38,6 +38,14 @@ ); } +export function updateAgentConversation(data) { + return axios.post( + '/api/v1/canvas/update_agent_conversation', + data + ); +} + + // 鑾峰彇浼氳瘽璇︽儏 export function getAgentSessionDetailsApi(id: string) { return axios.get( diff --git a/src/main.ts b/src/main.ts index ec48a6c..f4745fd 100644 --- a/src/main.ts +++ b/src/main.ts @@ -6,7 +6,6 @@ import store from './store'; import i18n from './locale'; import directive from './directive'; -import './mock'; import App from './App.vue'; diff --git a/src/views/dmx/IntelligentAgent/components/agentConfig.vue b/src/views/dmx/IntelligentAgent/components/agentConfig.vue index 9ff5baf..18b227b 100644 --- a/src/views/dmx/IntelligentAgent/components/agentConfig.vue +++ b/src/views/dmx/IntelligentAgent/components/agentConfig.vue @@ -575,7 +575,8 @@ } if (!max_tokens.value) { - formNew.llm_setting.max_tokens = ''; + //formNew.llm_setting.max_tokens = ''; + delete formNew.llm_setting.max_tokens; } setLoading(true); @@ -607,6 +608,7 @@ // console.log(props.formData,'浼犲叆鏁版嵁'); if (props.formData.llm_setting.max_tokens == '') { max_tokens.value = false; + delete props.formData.llm_setting.max_tokens; } else { max_tokens.value = true; } diff --git a/src/views/dmx/knowledgeLib/components/excel.vue b/src/views/dmx/knowledgeLib/components/excel.vue index 8735164..ca95456 100644 --- a/src/views/dmx/knowledgeLib/components/excel.vue +++ b/src/views/dmx/knowledgeLib/components/excel.vue @@ -8,6 +8,7 @@ </template> <script setup> + // 鑾峰彇鐖剁粍浠朵紶閫掔殑璧勬簮url const props = defineProps({ previewSrc: { @@ -18,7 +19,7 @@ }); //寮曞叆VueOfficeExcel缁勪欢鐩稿叧 import VueOfficeExcel from '@vue-office/excel'; - import '@vue-office/excel/lib/index.css'; + const comStyle = { width: '100%', diff --git a/src/views/dmx/knowledgeLib/components/txt.vue b/src/views/dmx/knowledgeLib/components/txt.vue index 0110ad9..391d664 100644 --- a/src/views/dmx/knowledgeLib/components/txt.vue +++ b/src/views/dmx/knowledgeLib/components/txt.vue @@ -1,6 +1,6 @@ <template> <div> - <pre v-html="content"></pre> + <pre v-text="content"></pre> </div> </template> @@ -8,6 +8,7 @@ import { ref, watch } from "vue"; let content = ref(""); + // 鑾峰彇鐖剁粍浠朵紶閫掔殑璧勬簮url const props = defineProps({ previewSrc: { @@ -17,14 +18,30 @@ } }); -const getContent = (url) => { - fetch(url) - .then((res) => res.text()) - .then((data) => { - content.value = data; - }); +//鐩戞帶灞炴�reviewSrc鐨勫彉鍖栵紝濡傛灉鍙戠敓鍙樺寲锛岄噸鏂拌幏鍙栧唴瀹� +watch( + () => props.previewSrc, + () => { + getContent(); + } +); + +const getContent = () => { + content.value=""; + fetch(props.previewSrc, { + responseType: "arraybuffer" + }).then( + (response) => { + return response.arrayBuffer(); + } + ).then( + (data) => { + const decoder = new TextDecoder('gbk'); + content.value = decoder.decode(data); + } + ); }; -getContent(props.previewSrc); +getContent(); const comStyle = { diff --git a/src/views/sessionManager/components/agentSession.vue b/src/views/sessionManager/components/agentSession.vue index 2e65936..484ad76 100644 --- a/src/views/sessionManager/components/agentSession.vue +++ b/src/views/sessionManager/components/agentSession.vue @@ -70,11 +70,7 @@ /> </template> <template #content> - <!-- <a-card :class="{ chatItemAnswer: theme === 'light' }">--> - <!-- <div :class="{ light: theme === 'light' }"--> - <!-- >{{ sessionDetail.content }}--> - <!-- </div>--> - <!-- </a-card>--> + <a-textarea readonly auto-size @@ -86,18 +82,7 @@ style="border: none" > </a-textarea> - <!-- <div class="prompt"> - <ul> - <li class="prompt-item" @click="copyText('43234')"> - <span> - 344343klsdjkjksdjkjksdjk灏卞紑濮嬪ぇ瀹剁湅鏁版嵁搴撶櫥璁板崱鍙楁墦鍑诲嚡鎾掔櫥璁板崱鍙楁墦鍑诲嚡鎾掔櫥璁板崱鍙楁墦鍑诲嚡鎾掔殑43</span - > - <span style="margin-left: 20px"> - <icon-right /> - </span> - </li> - </ul> - </div> --> + </template> <template #actions> <span @@ -189,19 +174,7 @@ <icon-send size="32" style="color: #0960bd" /> </a-button> </div> - <!-- <div class="btn-send">--> - <!-- <!– <icon-send size="32" /> –>--> - <!-- <a-button--> - <!-- :disabled="chatDis"--> - <!-- @click="sentClick"--> - <!-- type="text"--> - <!-- style="border-radius: 24px"--> - <!-- :loading="loading"--> - <!-- >--> - <!-- <icon-send size="32" style="color: #0960bd;"/>--> - <!-- </a-button--> - <!-- >--> - <!-- </div>--> + </div> <a-modal v-model:visible="visible" @@ -250,8 +223,8 @@ import { agentResetApi, agentSetApi, - getAgentSessionDetailsApi, - } from '@/api/agentSession'; + getAgentSessionDetailsApi, updateAgentConversation + } from "@/api/agentSession"; import EventBus from '@/utils/EventBus'; import useClipboard from 'vue-clipboard3'; import { addSessionApi, getSessionDetailsApi } from '@/api/session'; @@ -282,7 +255,7 @@ const selectValue = ref(''); const sectionList = ref({}); let chatObj = reactive({}); - const isStopChat = ref(false); + let isStopChat = false; const appStore = useAppStore(); const theme = computed(() => { return appStore.theme; @@ -295,6 +268,8 @@ let isHistory = ref(false); //鏄惁鏄巻鍙茶褰� let dsl = reactive({}); const chatDataMeg = reactive({}); + + let toStop = false; const rules = { name: [ @@ -377,7 +352,9 @@ 'Content-Type': 'application/json', }, body: JSON.stringify({ + converson_id: conversation_id.value, id: agentObj.id, + dsl:agentObj.dsl, }), }); @@ -420,7 +397,11 @@ if (code == 0) { console.log(data, 'agent浼氳瘽璇︽儏'); Object.assign(chatObj, data); - sessionDetailList.value = data.dsl.messages; + // sessionDetailList.value = data.dsl.messages; + await updateAgentConversation({ + converson_id: conversation_id.value, + dsl:data.dsl, + }) agentTitle.value = `${data.title}` || '鏈懡鍚嶄細璇�'; from.name = `${data.title}` || '鏈懡鍚嶄細璇�'; refreshScroll(); //鍒锋柊婊氬姩鏉′綅缃� @@ -498,7 +479,11 @@ } }; + let message_stop = []; + let message_id = ""; const startChat = async (valMsg) => { + isStopChat = false; + displayedText.value = ''; sessionDetailList.value.push({ content: valMsg, role: 'user', @@ -507,6 +492,7 @@ refreshScroll(); let chatStr = { id: agentObj.id, + converson_id: conversation_id.value, message: valMsg, }; if (isHistory.value) { @@ -527,6 +513,11 @@ .getReader(); currIndex.value = 0; while (true) { + if (isStopChat) { + message_stop.push(message_id); + setChatDataMeg(chatDataMeg); + break; + } const x = await reader?.read(); if (x) { const { done, value } = x; @@ -534,6 +525,16 @@ try { const val = JSON.parse(value?.data || ''); const d = val?.data; + if (message_id != d.message_id) { + message_id = d.message_id; + message_stop = []; + } else { + //message_stop涓煡鎵緈essage_id + const index = message_stop.findIndex(item => item === message_id); + if (index > -1) { + break; + } + } if (typeof d !== 'boolean') { console.info('data:', d); streamStr.value = d.content; @@ -543,15 +544,10 @@ console.warn(e); } if (done) { - console.info('done'); - displayedText.value = ''; - if (isStopChat.value) { - isStopChat.value = false; - setChatDataMeg(chatDataMeg); - } else { - queryAgentSessionDetail(agentObj.id); - EventBus.emit('queryAppUsageList'); - } + console.info("done"); + displayedText.value = ""; + queryAgentSessionDetail(agentObj.id); + EventBus.emit("queryAppUsageList"); break; } } @@ -561,13 +557,9 @@ }; const stopChat = async () => { - // const { code, data } = await stopChatApi(agentObj.id); - // if (code === 200) { - // Message.success("宸插仠姝�"); - // } loading.value = false; chatDis.value = false; - isStopChat.value = true; + isStopChat = true; console.log('stopChat'); console.log(displayedText.value, 'displayedText'); console.log(sessionDetailList.value, 'sessionDetailList'); @@ -656,7 +648,7 @@ watch( () => props.modalObj, (newVal, oldVal) => { - // Object.assign(agentObj, newVal); + Object.assign(agentObj, newVal); //璋冪敤agent鍒濆鍖栨柟娉� if (JSON.stringify(newVal) != '{}') { // initPage(); diff --git a/src/views/sessionManager/components/updataFile.vue b/src/views/sessionManager/components/updataFile.vue index 11ac03a..6e5f47b 100644 --- a/src/views/sessionManager/components/updataFile.vue +++ b/src/views/sessionManager/components/updataFile.vue @@ -19,6 +19,7 @@ :auto-upload="false" ref="uploadRef" @change="onChange" + :show-retry-button="false" multiple :limit="1" /> @@ -31,36 +32,6 @@ " class="upload-wrap" > -<!-- <div>--> -<!-- <span>瑙f瀽鏂规硶: </span>--> -<!-- <a-radio-group--> -<!-- v-model="parser_id"--> -<!-- style="width: 400px"--> -<!-- @change="parserChange"--> -<!-- >--> -<!-- <a-popover v-for="item in filterData" :key="item.value">--> -<!-- <a-radio :value="item.value" style="margin-right: 10px">{{--> -<!-- item.name--> -<!-- }}</a-radio>--> - -<!-- <template #content>--> -<!-- <p>{{ item.parser_config_str }}</p>--> -<!-- </template>--> -<!-- </a-popover>--> -<!-- </a-radio-group>--> -<!-- </div>--> -<!-- <a-select--> -<!-- :style="{ width: '100px', margin: '0 10px' }"--> -<!-- :default-value="['閫氱敤', '澶氭ā鎬�']"--> -<!-- v-model="parser_configs"--> -<!-- multiple--> -<!-- size="small"--> -<!-- >--> -<!-- <a-option v-for="item in parser_ids" :key="item.value">{{--> -<!-- item.name--> -<!-- }}</a-option>--> -<!-- </a-select>--> -<!-- <p class="config-text">鏇村閰嶇疆</p>--> <a-button :loading="onFileSelectedLoading" @click="upDataFile" @@ -396,7 +367,8 @@ watch( () => props.sessionId, - (value, oldValue) => { + (value) => { + activeSessionId.value = value; } ); diff --git a/src/views/sessionManager/index.vue b/src/views/sessionManager/index.vue index 00f9106..5a681db 100644 --- a/src/views/sessionManager/index.vue +++ b/src/views/sessionManager/index.vue @@ -121,7 +121,7 @@ /> </template> <template #content> - <a-card v-if="isExistTip(sessionDetail.content)"> + <a-card v-if="isExistTip(sessionDetail.content)" style="padding: 10px"> <div :class="{ chatItemAnswer: theme === 'light' }" :style="{ @@ -160,10 +160,13 @@ " > <img - style="width: 20px; height: 20px" + style="width: 15px; height: 15px" :src="tipImage" /> </a-tooltip> + <span v-if="tipIndex == item.len - 1"> + {{ breakContent.substring(item.index + 5) }} + </span> </span> <span v-else-if="tipIndex == item.len - 1"> {{ @@ -179,7 +182,7 @@ " > <img - style="width: 20px; height: 20px" + style="width: 15px; height: 15px" :src="tipImage" /> </a-tooltip> @@ -199,7 +202,7 @@ " > <img - style="width: 20px; height: 20px" + style="width: 15px; height: 15px" :src="tipImage" /> </a-tooltip> @@ -238,12 +241,9 @@ </ul> </div> --> </template> - <!-- <div>{{ sessionDetail.role === 'assistant' }}</div> --> + <template #actions> - <!-- <div - v-for="(item, leng) in messagenList.reference" - :key="leng" - > --> + <div> <div> <template @@ -308,12 +308,7 @@ </template> <template #actions> - <!-- <div class="icon-box"> - <div> - <img :src="getIconByExtension('pdf')" alt="" /> - </div> - <div class="icon-text"> 鏂囦欢绫诲瀷 </div> - </div> --> + <div class="action" @click="stopChat" @@ -329,24 +324,12 @@ </template> </a-comment> </div> - <!-- <div class="chartStart" v-if="isStart" @click="startChat" - >鍋滄鐢熸垚</div - > - <div class="chartStart v-else" @click="stopChat">閲嶆柊鐢熸垚</div> --> + </a-scrollbar> <div class="chat_bottom"> <div class="center-bottom"> - <!-- <a-textarea - v-model="inputMsg" - @keydown.shift.enter="sendMessage" - style="height: 180px" - placeholder="杈撳叆鎮ㄦ兂浜嗚В鐨勫唴瀹癸紝Shift+Enter鍙戦��" - :max-length="500" - allow-clear - show-word-limit - > - </a-textarea> --> + <a-textarea v-model="inputMsg" @keydown.shift.enter="handleShiftEnter" @@ -382,12 +365,6 @@ :sessionId="activeSessionId" @selectFileCallback="selectFileCallback" ></updataFile> - <!-- <uploadFile - ref="fileInput" - :handleRemove="handleRemove" - :typeXLse="false" - @selectFileCallback="selectFileCallback" - ></uploadFile> --> <a-button :disabled="chatDis" @@ -483,11 +460,10 @@ </a-col> </a-row> <a-modal title=" " v-model:visible="fileVisible" :footer="false" fullscreen> - <!-- <docx previewSrc="http://192.168.20.116:1080/v1/document/get/405c3efa4d8c11ef97560242ac120006"></docx>--> <docx v-if="documenttype == 'docx'" :previewSrc="previewSrc"></docx> - <excel v-if="documenttype == 'xlsx'" :previewSrc="previewSrc"></excel> + <excel v-if="documenttype == ('xlsx' || 'xls')" :previewSrc="previewSrc"></excel> <Pdf v-if="documenttype == 'pdf'" :previewSrc="previewSrc"></Pdf> - <txt v-if="documenttype == 'txt'" :previewSrc="previewSrc"></txt> + <txt v-if="documenttype == 'txt'" :previewSrc="previewSrc"></txt> </a-modal> <a-modal v-model:visible="visible" @@ -591,7 +567,7 @@ let from = reactive({ name: '鏈懡鍚嶄細璇�', }); - const isStopChat = ref(false); + const currIndex = ref(0); const displayedText = ref(''); // 姝e湪鏄剧ず鐨勬枃瀛� let timer: number | null = null; @@ -712,7 +688,7 @@ const clickHref = async (item) => { documenttype.value = item.doc_name.split('.').pop(); - previewSrc.value = httpUrl + `/api/v1/document/get/${item.doc_id}`; + previewSrc.value = httpUrl + `/api/v1/document/get/${item.doc_id}`+"?t="+new Date().getTime(); fileVisible.value = true; }; @@ -780,53 +756,6 @@ activeSessionId.value = conversation_id; }; - //涓婁紶 - // const selectFileCallback = async (resData, file) => { - // console.log(111); - // try { - // const formData = new FormData(); - // uploaditemList.value = resData; - // uploaditemList.value.map((item) => { - // if (item.name == file[0].file.name) { - // item.onFileSelectedLoading = true; - // item.textName = '涓婁紶涓�'; - // } - // return item; - // }); - // debugger; - // if (!activeSessionId.value) { - // await createSession(resData); - // } - - // // onFileSelectedLoading.value = true; - // // textName.value = '涓婁紶涓�'; - - // formData.append('files', file[0].file); - // formData.append('conversation_id', activeSessionId.value); - - // console.log(formData, 'formData'); - // const { data, code } = await uploadAndParse(formData); - // if (code === 200) { - // uploaditemList.value.map((item: any) => { - // item.onFileSelectedLoading = false; - // item.textName = '涓婁紶鎴愬姛'; - // return item; - // }); - // getInfo(data); - // // onFileSelectedLoading.value = false; - // // textName.value = '涓婁紶鎴愬姛'; - // } - // } catch (err) { - // uploaditemList.value.map((item: any) => { - // item.onFileSelectedLoading = false; - // item.textName = '涓婁紶澶辫触'; - // return item; - // }); - // // onFileSelectedLoading.value = false; - // // textName.value = '涓婁紶澶辫触'; - // Message.error('涓婁紶澶辫触'); - // } - // }; //涓婁紶鎴愬姛瑙f瀽getinfo const getInfo = async (id) => { @@ -942,6 +871,7 @@ // 鍙戦�� const sentClick = () => { + displayedText.value=""; sendMessage('click'); uploaditemList.value = []; }; @@ -1000,11 +930,14 @@ } }; + let message_stop = []; + let message_id = ""; const startChat = async (valMsg) => { chatDis.value = true; loading.value = true; - chartLoading.value = true; toStop = false; + displayedText.value = ''; + chartLoading.value = true; sessionDetailList.value.push({ content: valMsg, role: 'user', @@ -1033,6 +966,7 @@ currIndex.value = 0; while (true) { if (toStop) { + message_stop.push(message_id); displayedText.value = ''; setChatDataMeg(chatDataMeg); break; @@ -1044,6 +978,16 @@ try { const val = JSON.parse(value?.data || ''); const d = val?.data; + if (message_id != d.message_id) { + message_id = d.message_id; + message_stop = []; + } else { + //message_stop涓煡鎵緈essage_id + const index = message_stop.findIndex(item => item === message_id); + if (index > -1) { + break; + } + } if (typeof d !== 'boolean') { // console.info("data:", d); streamStr.value = d.content; @@ -1057,12 +1001,8 @@ console.info('done'); displayedText.value = ''; chartLoading.value = false; - if (isStopChat.value) { - setChatDataMeg(chatDataMeg); - } else { - queryNewSessionDetail(activeSessionId.value); - EventBus.emit('queryAppUsageList'); - } + queryNewSessionDetail(activeSessionId.value); + EventBus.emit('queryAppUsageList'); break; } } @@ -1073,14 +1013,8 @@ }; const stopChat = async () => { - // const { code, data } = await stopChatApi(activeSessionId.value); - // if (code === 200) { - // Message.success("宸插仠姝�"); - // queryNewSessionDetail(activeSessionId.value); - // } loading.value = false; chatDis.value = false; - isStopChat.value = true; toStop = true; console.log('stopChat'); console.log(displayedText.value, 'displayedText'); @@ -1103,7 +1037,9 @@ .concat(lastArr); console.log(sessionDetailList.value, 'sessionDetailList2'); console.log(chatObj, 'chatObj瀵硅薄'); - chatObj.message = chatObj.message.concat(lastArr); + if (chatObj?.message) { + chatObj.message = chatObj.message.concat(lastArr); + } Object.assign(chatDataMeg, { id: chatObj.id, conversation_id: chatObj.id, @@ -1133,7 +1069,6 @@ agentTitle.value = data.name; from.name = data.name; refreshScroll(); //鍒锋柊婊氬姩鏉′綅缃� - isStopChat.value = false; } }; @@ -1205,6 +1140,7 @@ // fileInput.value.cancel(); }); EventBus.on('newChat', () => { + uploaditemList.value = []; agentType.value = '1'; // createSession(''); activeSessionId.value = ''; diff --git a/yarn.lock b/yarn.lock index 59a7c00..e9fcbee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1018,7 +1018,7 @@ "@vue-office/excel@^1.7.11": version "1.7.11" - resolved "https://registry.npmmirror.com/@vue-office/excel/-/excel-1.7.11.tgz" + resolved "https://registry.npmmirror.com/@vue-office/excel/-/excel-1.7.11.tgz#e37e5a2c212907a62c9b65e42d9df21f9c68a2cc" integrity sha512-LF3R9IV573Sf4qTu6Ik5Ee8UMfkrsZQ6HEQE25/2m1c0CMcHX6KanIy6Cz0b0Q+FrLH3TjIsLTm6oPcqAbDGSA== "@vue-office/pdf@^2.0.2": -- Gitblit v1.8.0