Explorar el Código

基础的消息重试功能

kagg886 hace 2 meses
padre
commit
ff917a6c2e
Se han modificado 1 ficheros con 114 adiciones y 23 borrados
  1. 114 23
      src/views/assistant/index.vue

+ 114 - 23
src/views/assistant/index.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { ref, nextTick, onMounted, computed, onUnmounted, reactive, watch } from 'vue'
+import { ref, nextTick, onMounted, computed, onUnmounted, reactive, watch, isReactive } from 'vue'
 import { Local } from '/@/utils/storage'
 import { User, ChatDotRound, Delete, Edit, Check, Close } from '@element-plus/icons-vue'
 import { MarkdownPlugin } from '/@/components/markdown/type/markdown'
@@ -126,30 +126,84 @@ const sendMessage = () => {
 		tool_calls: [],
 	})
 
-	const fn = watch(
-		() => rtn.render_content,
-		(newVal) => console.log(newVal)
-	)
-
 	inputMessage.value = ''
-
 	scrollToBottom()
-	//
-	// let toolcall: { name: string; param?: string; value?: string } | undefined = undefined
+	chatInternal(rtn)
+	messages.value.push(rtn)
+}
+
+const replaceMessage = (index: number) => {
+	// 获取当前用户消息
+	const userMessage = messages.value[index]
+	if (!userMessage || userMessage.role !== 'user') {
+		return
+	}
+
+	// 查找对应的AI回复消息(通常是下一条消息)
+	let aiMessageIndex = -1
+	for (let i = index + 1; i < messages.value.length; i++) {
+		if (messages.value[i].role === 'assistant') {
+			aiMessageIndex = i
+			break
+		}
+	}
+
+	let rtn: Message
+
+	if (aiMessageIndex !== -1) {
+		// 找到了AI回复消息
+		const aiMessage = messages.value[aiMessageIndex]
+
+		if (isReactive(aiMessage)) {
+			// 如果是reactive对象,清空内容
+			aiMessage.render_content = ''
+			aiMessage.content = ''
+			aiMessage.tool_calls = []
+			rtn = aiMessage
+		} else {
+			// 如果不是reactive对象,创建新的reactive对象替换
+			rtn = reactive<Message>({
+				id: aiMessage.id,
+				role: 'assistant',
+				render_content: '',
+				content: '',
+				timestamp: aiMessage.timestamp,
+				tool_calls: [],
+			})
+			messages.value[aiMessageIndex] = rtn
+		}
+	} else {
+		// 没有找到AI回复消息,创建新的
+		rtn = reactive<Message>({
+			id: `${Date.now()}`,
+			role: 'assistant',
+			render_content: '',
+			content: '',
+			timestamp: Date.now(),
+			tool_calls: [],
+		})
+		messages.value.push(rtn)
+	}
+
+	// 重新发起对话
+	chatInternal(rtn,messages.value.slice(0,aiMessageIndex))
+}
+
+const chatInternal = (rtn:Message,context: Message[] = messages.value) => {
 	chatInstance.value = assist.chat({
 		chatRequest: {
 			message: prompt.value
 				? [
-						{
-							id: `${Date.now()}`,
-							role: 'system',
-							render_content: prompt.value,
-							content: prompt.value,
-							timestamp: Date.now(),
-						},
-						...messages.value,
-				  ]
-				: messages.value,
+					{
+						id: `${Date.now()}`,
+						role: 'system',
+						render_content: prompt.value,
+						content: prompt.value,
+						timestamp: Date.now(),
+					},
+					...context,
+				]
+				: context,
 			modelClassId: selectedModel.value,
 		},
 		onReceive: (resp: ChatResponse) => {
@@ -211,7 +265,6 @@ ${resp.request.data.replace('\n', '')}
 			}
 		},
 		onComplete: (e) => {
-			fn()
 			if (e !== undefined) {
 				rtn.content += `
 
@@ -221,7 +274,7 @@ ${resp.request.data.replace('\n', '')}
 			chatInstance.value = undefined
 		},
 	})
-	messages.value.push(rtn)
+
 }
 
 // 终止对话
@@ -401,8 +454,21 @@ const redirectToModelManager = () => router.push('manage/model')
 
 						<!-- 用户消息 -->
 						<div v-if="message.role === 'user'" class="user-message-container">
-							<div class="message-bubble user-bubble">
-								{{ message.render_content }}
+							<div class="user-message-content">
+								<div class="message-bubble user-bubble">
+									{{ message.render_content }}
+								</div>
+								<div class="user-message-actions">
+									<el-button
+										type="primary"
+										size="small"
+										@click="replaceMessage(messages.indexOf(message))"
+										class="retry-btn"
+										plain
+									>
+										重试
+									</el-button>
+								</div>
 							</div>
 							<el-avatar class="message-avatar" :src="getUserInfos.avatar" :icon="User" />
 						</div>
@@ -739,6 +805,31 @@ const redirectToModelManager = () => router.push('manage/model')
 	justify-content: flex-end;
 }
 
+.user-message-content {
+	display: flex;
+	flex-direction: column;
+	align-items: flex-end;
+	gap: 8px;
+}
+
+.user-message-actions {
+	display: flex;
+	justify-content: flex-end;
+	opacity: 0;
+	transition: opacity 0.2s ease;
+}
+
+.user-message-container:hover .user-message-actions {
+	opacity: 1;
+}
+
+.retry-btn {
+	font-size: 12px;
+	padding: 4px 12px;
+	height: 24px;
+	border-radius: 12px;
+}
+
 .user-bubble {
 	background: var(--el-color-primary);
 	color: white;