diff --git a/src/components/xt-chat/chat-view/constants.ts b/src/components/xt-chat/chat-view/constants.ts index 0830afc..c5575e6 100644 --- a/src/components/xt-chat/chat-view/constants.ts +++ b/src/components/xt-chat/chat-view/constants.ts @@ -34,7 +34,10 @@ export interface UseChatHandlerReturn { senderRef: Ref } export enum EnumTeamRunStatus { - TeamRunStarted = 'TeamRunStarted', // 开始 - TeamRunResponseContent = 'TeamRunResponseContent', // 执行中 - TeamRunCompleted = 'TeamRunCompleted', // 完成 + TeamRunStarted = 'TeamRunStarted', // 对话开始 + TeamRunResponseContent = 'TeamRunResponseContent', // 对话执行中 + TeamRunCompleted = 'TeamRunCompleted', // 对话完成 + RunStarted = 'RunStarted', // l2开始运行 + RunResponseContent = 'RunResponseContent', // l2执行中 + RunCompleted = 'RunCompleted', // l2完成 } diff --git a/src/components/xt-chat/chat-view/index.vue b/src/components/xt-chat/chat-view/index.vue index 4aaa9b3..0eb1db1 100644 --- a/src/components/xt-chat/chat-view/index.vue +++ b/src/components/xt-chat/chat-view/index.vue @@ -37,6 +37,7 @@ export default { antdMessage.warning('停止生成后可发送'); return; } + conversationList.value.push({ role: QUESTION_ROLE, content: message, @@ -47,6 +48,7 @@ export default { const handleCancel = () => { // 中止当前正在输出的回答 + console.log('handleCancel', currentTaskId.value) if (generateLoading.value) { bubbleListRef.value?.abortTypingByKey(currentTaskId.value); sseController.value?.abort?.(); @@ -105,9 +107,10 @@ export default { () => props.inputInfo, (newVal) => { if (newVal) { + const { message } = newVal; conversationList.value.push({ role: QUESTION_ROLE, - content: newVal, + content: message, }); initSse(newVal); } diff --git a/src/components/xt-chat/chat-view/useChatHandler.tsx b/src/components/xt-chat/chat-view/useChatHandler.tsx index b000a47..cf493a6 100644 --- a/src/components/xt-chat/chat-view/useChatHandler.tsx +++ b/src/components/xt-chat/chat-view/useChatHandler.tsx @@ -39,6 +39,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { const currentTaskId = ref(null); const showRightView = ref(false); const rightViewInfo = ref({}); + const lastTeamRunTaskId = ref(null); // 最近一个对话的id // 初始化markdown const md = markdownit({ @@ -145,7 +146,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { // style: ANSWER_STYLE, // footer: ({ item }: { item: any }) => { // const nonQuestionElements = conversationList.value.filter((item) => item.role !== QUESTION_ROLE); - // const isLastAnswer = nonQuestionElements[nonQuestionElements.length - 1]?.id === item.id; + // const isLastRunTask = nonQuestionElements[nonQuestionElements.length - 1]?.id === item.id; // }, // }); }; @@ -161,23 +162,62 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { // antdMessage.error('连接服务器失败'); // }; - const handleTaskStart = (data: MESSAGE.Answer) => { + const onRefresh = (run_id: string) => { + generateLoading.value = true; + conversationList.value = conversationList.value.filter((item) => item.run_id !== run_id); + initSse({ message: senderRef.value?.searchValue }); + }; + + // 获取同一个对话下的最后一个run_task + const getLastRunTask = (data: MESSAGE.Answer, teamRunTaskId: string) => { + const allRunTask = conversationList.value.filter( + (item) => item.role === ANSWER_ROLE && item.team_run_id === teamRunTaskId && !item.isTeamRunTask, + ); + return allRunTask[allRunTask.length - 1] ?? {}; + }; + const getFirstRunTask = (data: MESSAGE.Answer, teamRunTaskId: string) => { + const allRunTask = conversationList.value.filter( + (item) => item.role === ANSWER_ROLE && item.team_run_id === teamRunTaskId && !item.isTeamRunTask, + ); + return allRunTask[0] ?? {}; + }; + const isLastRunTask = (data: MESSAGE.Answer, teamRunTaskId: string): boolean => { + const { run_id } = data; + return getLastRunTask(data, teamRunTaskId).run_id === run_id; + }; + const isFirstRunTask = (data: MESSAGE.Answer, teamRunTaskId: string): boolean => { + const { run_id } = data; + return getFirstRunTask(data, teamRunTaskId).run_id === run_id; + }; + + const isLastTeamRunTask = (data: MESSAGE.Answer) => { + const { run_id } = data; + const lastElement = conversationList.value[conversationList.value.length - 1]; + return lastElement && lastElement.run_id === run_id; + }; + + // 过程节点开始 + const handleRunTaskStart = (data: MESSAGE.Answer) => { const { run_id } = data; currentTaskId.value = run_id; conversationList.value.push({ run_id, + key: run_id, + team_run_id: lastTeamRunTaskId.value, content: data, output: data.output, role: ANSWER_ROLE, messageRender: (data: MESSAGE.Answer) => { let outputEleClass: string = `thought-chain-output border-l-#E6E6E8 border-l-1px pl-12px relative left-6px mb-4px`; - !isLastAnswer(data) && (outputEleClass += ' hasLine pb-12px pt-4px'); + !isLastRunTask(data, lastTeamRunTaskId.value) && (outputEleClass += ' hasLine pb-12px pt-4px'); return ( <> -
- 智能思考 - -
+ {isFirstRunTask(data, lastTeamRunTaskId.value) && ( +
+ 智能思考 + +
+ )}
@@ -190,51 +230,67 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { }, }); }; - - const onRefresh = (run_id: string) => { - generateLoading.value = true; - conversationList.value = conversationList.value.filter((item) => item.run_id !== run_id); - initSse({ message: senderRef.value?.searchValue }); - }; - - const isLastAnswer = (data: MESSAGE.Answer) => { - const { run_id } = data; - const nonQuestionElements = conversationList.value.filter( - (item) => item.role === ANSWER_ROLE && item.run_id === run_id, - ); - return nonQuestionElements[nonQuestionElements.length - 1]?.run_id === run_id; - }; - - const isLastTask = (data: MESSAGE.Answer) => { - const { run_id } = data; - const lastElement = conversationList.value[conversationList.value.length - 1]; - return lastElement && lastElement.run_id === run_id; - }; - - // 节点更新处理 - const handleTaskUpdate = (data: MESSAGE.Answer) => { + // 过程节点更新 + const handleRunTaskUpdate = (data: MESSAGE.Answer) => { const { run_id, output } = data; - const existingItemIndex = conversationList.value.findIndex((item) => item.run_id === run_id); + const existingItem = conversationList.value.find((item) => item.run_id === run_id); + if (existingItem && output) { + existingItem.content.output += output; + } + }; + // 过程节点结束 + const handleRunTaskEnd = (data: MESSAGE.Answer) => { + const { run_id, output } = data; - if (existingItemIndex !== -1 && output) { - const existingItem = conversationList.value[existingItemIndex]; + const existingItem = conversationList.value.find((item) => item.run_id === run_id); + + if (existingItem) { existingItem.content.output += output; } }; - const handleTaskEnd = (data: MESSAGE.Answer) => { - const { run_id, output, team_session_state } = data; - + // 任务开始 + const handleTeamRunTaskStart = (data: MESSAGE.Answer) => { + // console.log('handleRunTaskStart'); + const { run_id } = data; + lastTeamRunTaskId.value = run_id; + currentTaskId.value = run_id; + conversationList.value.push({ + run_id, + isTeamRunTask: true, + team_run_id: lastTeamRunTaskId.value, + key: run_id, + content: data, + output: data.output, + role: ANSWER_ROLE, + messageRender: (data: MESSAGE.Answer) => { + return
; + }, + }); + }; + // 任务更新 + const handleTeamRunTaskUpdate = (data: MESSAGE.Answer) => { + const { run_id, output } = data; const existingItem = conversationList.value.find((item) => item.run_id === run_id); - resetGenerateStatus(); - - if (existingItem) { + if (existingItem && output) { existingItem.content.output += output; - existingItem.footer = ({ item: any }) => { + } + }; + // 任务结束 + const handleTeamRunTaskEnd = (data: MESSAGE.Answer) => { + const { run_id, team_session_state } = data; + + const lastRunTask = getLastRunTask(data, lastTeamRunTaskId.value); + + resetGenerateStatus(); + console.log('handleTeamRunTaskEnd', { data }, { lastRunTask }); + + if (lastRunTask) { + lastRunTask.footer = () => { return (
- onCopy(existingItem.content.output)}> + onCopy(lastRunTask.content.output)}> {team_session_state && ( @@ -242,7 +298,7 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { )} - {isLastTask(data) && ( + {isLastTeamRunTask(data) && ( onRefresh(run_id)}> @@ -256,19 +312,29 @@ export default function useChatHandler({ initSse }): UseChatHandlerReturn { handleFileReview(data); } }; + // 消息处理主函数 const handleMessage = (parsedData: { event: string; data: MESSAGE.Answer }) => { const { data } = parsedData; const { status } = data; switch (status) { + case EnumTeamRunStatus.RunStarted: + handleRunTaskStart(data); + break; + case EnumTeamRunStatus.RunResponseContent: + handleRunTaskUpdate(data); + break; + case EnumTeamRunStatus.RunCompleted: + handleRunTaskEnd(data); + break; case EnumTeamRunStatus.TeamRunStarted: - handleTaskStart(data); + handleTeamRunTaskStart(data); break; case EnumTeamRunStatus.TeamRunResponseContent: - handleTaskUpdate(data); + handleTeamRunTaskUpdate(data); break; case EnumTeamRunStatus.TeamRunCompleted: - handleTaskEnd(data); + handleTeamRunTaskEnd(data); break; default: break; diff --git a/src/components/xt-chat/xt-bubble/xt-bubbleList.vue b/src/components/xt-chat/xt-bubble/xt-bubbleList.vue index 8404bcf..89026b3 100644 --- a/src/components/xt-chat/xt-bubble/xt-bubbleList.vue +++ b/src/components/xt-chat/xt-bubble/xt-bubbleList.vue @@ -105,7 +105,6 @@ export default defineComponent({ // 暴露控制方法 const abortTypingByKey = (key: string | number) => { bubbleRefs.value[key]?.abortTyping?.(); - console.log('abortTypingByKey----', bubbleRefs.value[key]) }; // 对外暴露能力 expose({ diff --git a/src/layouts/Basic.vue b/src/layouts/Basic.vue index 0f2c0cb..4f31f77 100644 --- a/src/layouts/Basic.vue +++ b/src/layouts/Basic.vue @@ -36,9 +36,9 @@ const showInOnePage = computed(() => { const layoutPageClass = computed(() => { let result = showInOnePage.value ? 'overflow-hidden' : ''; if (isHomeRoute.value) { - result += 'pb-8px pr-8px'; + result += ' pb-8px pr-8px'; } else { - result += 'pb-24px pr-24px'; + result += ' pb-24px pr-24px'; } return result; }); diff --git a/src/types/message.ts b/src/types/message.ts index fcd7483..d8e3c3c 100644 --- a/src/types/message.ts +++ b/src/types/message.ts @@ -1,18 +1,25 @@ declare global { namespace MESSAGE { - type TASK_STATUS = 'TeamRunStarted' | 'TeamRunResponseContent' | 'TeamRunCompleted'; + type TASK_STATUS = + | 'RunStarted' + | 'RunResponseContent' + | 'RunCompleted' + | 'TeamRunStarted' + | 'TeamRunResponseContent' + | 'TeamRunCompleted'; interface Answer { message: string; node: string; output: string; run_id: string; + team_run_id: string; status: TASK_STATUS; extra_data: { - type: string, - data: Record - }, - team_session_state: any + type: string; + data: Record; + }; + team_session_state: any; } } }