refactor: 推理对比超时与打字机展示改进

抽取 withTimeout 替代 Promise.race 超时控制,对比结果新增打字机逐字渲染与清理,推理聊天参数与列表类型同步收敛。
This commit is contained in:
caoxiaozhu
2026-07-16 11:03:25 +08:00
parent 5a040366da
commit ab9e87f948
4 changed files with 83 additions and 42 deletions

View File

@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ref, reactive, nextTick, onMounted } from 'vue'
import { ref, reactive, nextTick, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import MarkdownView from '@/components/MarkdownView.vue'
@@ -34,6 +34,7 @@ const temperature = ref(0.7)
const top_p = ref(0.95)
const maxTokens = ref(2048)
const contentRef = ref<HTMLElement>()
let activeAssistant: ChatMessage | null = null
/** 设置面板抽屉 */
const showSettings = ref(false)
@@ -98,8 +99,8 @@ async function handleSend() {
return
}
// 监听流式 message 变化,同步到 assistantMsg
const watchStop = watchMessage(assistantMsg)
// 流式状态变化时只同步当前回复,避免固定定时器空转。
activeAssistant = assistantMsg
await send({
port: target.port,
@@ -118,7 +119,7 @@ async function handleSend() {
assistantMsg.isThinking = false
assistantMsg.isStreaming = false
assistantMsg.done = true
watchStop()
activeAssistant = null
reset()
await nextTick()
scrollToBottom()
@@ -149,17 +150,24 @@ async function mockReply(assistantMsg: ChatMessage, question: string) {
scrollToBottom()
}
/** 轮询同步流式状态到展示消息 */
function watchMessage(assistantMsg: ChatMessage) {
const timer = setInterval(() => {
assistantMsg.content = message.value.displayContent
assistantMsg.think = message.value.thinkContent
assistantMsg.isThinking = message.value.isThinking
if (message.value.done) clearInterval(timer)
watch(
() => [
message.value.displayContent,
message.value.thinkContent,
message.value.isThinking,
message.value.done,
] as const,
async ([content, think, isThinking, done]) => {
if (!activeAssistant) return
activeAssistant.content = content
activeAssistant.think = think
activeAssistant.isThinking = isThinking
activeAssistant.isStreaming = !done
await nextTick()
scrollToBottom()
}, 80)
return () => clearInterval(timer)
}
},
{ flush: 'post' },
)
function scrollToBottom() {
if (contentRef.value) {
@@ -168,6 +176,7 @@ function scrollToBottom() {
}
function handleNewChat() {
activeAssistant = null
messages.value = []
reset()
}