From 3e0b18d4559b0f2717f7263468ce16363dea3fa3 Mon Sep 17 00:00:00 2001 From: zhaoshibao <501348474@qq.com> Date: Sun, 30 Mar 2025 11:57:06 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=81=9C?= =?UTF-8?q?=E6=AD=A2=E5=A4=A7=E6=A8=A1=E5=9E=8B=E5=9B=9E=E7=AD=94=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=88=E5=85=B3=E8=81=94=20Issue=20#104=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/ChatComponent.vue | 106 ++++++++++++++++++++++++--- 1 file changed, 97 insertions(+), 9 deletions(-) diff --git a/web/src/components/ChatComponent.vue b/web/src/components/ChatComponent.vue index 8897f71d..85b3e161 100644 --- a/web/src/components/ChatComponent.vue +++ b/web/src/components/ChatComponent.vue @@ -100,6 +100,10 @@ > 请求错误,请重试。{{ message.message }} +
+ 你停止生成了本次回答 + 重新编辑问题 +
@@ -153,9 +157,19 @@
- - - + + + + +
@@ -188,6 +202,7 @@ import { RobotOutlined, CaretRightOutlined, DeploymentUnitOutlined, + StopOutlined } from '@ant-design/icons-vue' import { onClickOutside } from '@vueuse/core' import { Marked } from 'marked'; @@ -456,6 +471,9 @@ const loadDatabases = () => { // 新函数用于处理 fetch 请求 const fetchChatResponse = (user_input, cur_res_id) => { + const controller = new AbortController(); + const signal = controller.signal; + fetch('/api/chat/', { method: 'POST', body: JSON.stringify({ @@ -466,7 +484,8 @@ const fetchChatResponse = (user_input, cur_res_id) => { }), headers: { 'Content-Type': 'application/json' - } + }, + signal // 添加 signal 用于中断请求 }) .then((response) => { if (!response.body) throw new Error("ReadableStream not supported."); @@ -524,13 +543,24 @@ const fetchChatResponse = (user_input, cur_res_id) => { readChunk(); }) .catch((error) => { - console.error(error); - updateMessage({ - id: cur_res_id, - status: "error", - }); + if (error.name === 'AbortError') { + console.log('Fetch aborted'); + } else { + console.error(error); + updateMessage({ + id: cur_res_id, + status: "error", + }); + } isStreaming.value = false; }); + + // 监听 isStreaming 变化,当为 false 时中断请求 + watch(isStreaming, (newValue) => { + if (!newValue) { + controller.abort(); + } + }); } @@ -607,6 +637,36 @@ watch( }, { deep: true } ); + +// 处理发送或停止 +const handleSendOrStop = () => { + if (isStreaming.value) { + // 停止生成 + isStreaming.value = false; + const lastMessage = conv.value.messages[conv.value.messages.length - 1]; + if (lastMessage) { + lastMessage.isStoppedByUser = true; + lastMessage.status = 'stopped'; + } + } else { + // 发送消息 + sendMessage(); + } +} + +// 重试被停止的消息 +const retryStoppedMessage = (message) => { + // 找到用户的原始问题 + const messageIndex = conv.value.messages.findIndex(msg => msg.id === message.id); + if (messageIndex > 0) { + const userMessage = conv.value.messages[messageIndex - 1]; + if (userMessage && userMessage.role === 'sent') { + conv.value.inputText = userMessage.text; + // 删除被停止的消息 + conv.value.messages = conv.value.messages.slice(0, messageIndex); + } + } +} From 2207484eae2fe6c84d04cba4efe430b60a967ec5 Mon Sep 17 00:00:00 2001 From: zhaoshibao <501348474@qq.com> Date: Sun, 30 Mar 2025 12:31:36 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=81=9C?= =?UTF-8?q?=E6=AD=A2=E5=A4=A7=E6=A8=A1=E5=9E=8B=E5=9B=9E=E7=AD=94=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=EF=BC=88=E5=85=B3=E8=81=94=20Issue=20#104=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/ChatComponent.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/src/components/ChatComponent.vue b/web/src/components/ChatComponent.vue index ca4d0811..ad824d03 100644 --- a/web/src/components/ChatComponent.vue +++ b/web/src/components/ChatComponent.vue @@ -684,6 +684,7 @@ const retryStoppedMessage = (message) => { conv.value.messages = conv.value.messages.slice(0, messageIndex); } } +} const modelNames = computed(() => configStore.config?.model_names) const modelStatus = computed(() => configStore.config?.model_provider_status) @@ -1241,6 +1242,9 @@ const selectModel = (provider, name) => { &:hover { background-color: #ff7875 !important; } + } +} + .scrollable-menu { max-height: 300px; overflow-y: auto; From c25278cec392c6286348bb5c49a709dca4abb881 Mon Sep 17 00:00:00 2001 From: zhaoshibao <501348474@qq.com> Date: Sun, 30 Mar 2025 14:51:18 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=AF=B9?= =?UTF-8?q?=E8=AF=9D=E9=87=8D=E6=96=B0=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=EF=BC=88=E5=85=B3=E8=81=94=20Issue=20#104=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/components/ChatComponent.vue | 27 +++++++++++++++++++++++++-- web/src/components/RefsComponent.vue | 13 ++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/web/src/components/ChatComponent.vue b/web/src/components/ChatComponent.vue index ad824d03..3187c1ea 100644 --- a/web/src/components/ChatComponent.vue +++ b/web/src/components/ChatComponent.vue @@ -122,7 +122,7 @@ 你停止生成了本次回答 重新编辑问题 - +
@@ -220,7 +220,9 @@ import { BulbOutlined, CaretRightOutlined, DeploymentUnitOutlined, - StopOutlined + StopOutlined, + ReloadOutlined, + CopyOutlined } from '@ant-design/icons-vue' import { onClickOutside } from '@vueuse/core' import { Marked } from 'marked'; @@ -702,6 +704,24 @@ const selectModel = (provider, name) => { message.success(`已切换到模型: ${provider}/${name}`) } + +// 添加重新生成方法 +const regenerateMessage = (message) => { + // 找到用户的原始问题 + const messageIndex = conv.value.messages.findIndex(msg => msg.id === message.id) + if (messageIndex > 0) { + const userMessage = conv.value.messages[messageIndex - 1] + if (userMessage && userMessage.role === 'sent') { + // 删除当前AI回复 + conv.value.messages = conv.value.messages.slice(0, messageIndex) + // 重新生成回答 + appendAiMessage("", null) + const cur_res_id = conv.value.messages[conv.value.messages.length - 1].id + isStreaming.value = true + fetchChatResponse(userMessage.text, cur_res_id) + } + } +}