(queryText: string, userMessageId: string, assistantMessageId: string)
| 187 | |
| 188 | // 处理生成回复的逻辑(从handleSubmit中提取出来的核心部分) |
| 189 | const handleGenerateResponse = async (queryText: string, userMessageId: string, assistantMessageId: string) => { |
| 190 | try { |
| 191 | // 创建新的AbortController |
| 192 | if (abortControllerRef.current) { |
| 193 | abortControllerRef.current.abort() // 取消之前的请求(如果有) |
| 194 | } |
| 195 | abortControllerRef.current = new AbortController() |
| 196 | |
| 197 | setIsStreaming(true) |
| 198 | |
| 199 | // 准备对话历史 |
| 200 | const conversationHistory = messages |
| 201 | .filter((m) => m.role === "user" || m.role === "assistant") |
| 202 | .map((m) => ({ |
| 203 | role: m.role, |
| 204 | content: m.content, |
| 205 | })) |
| 206 | |
| 207 | // 添加当前用户消息 |
| 208 | conversationHistory.push({ |
| 209 | role: "user", |
| 210 | content: queryText, |
| 211 | }) |
| 212 | |
| 213 | // 开始流式响应,传入AbortSignal |
| 214 | const stream = await generateStreamingResponseClient(conversationHistory, abortControllerRef.current.signal) |
| 215 | |
| 216 | if (!stream) { |
| 217 | throw new Error("无法创建流式响应") |
| 218 | } |
| 219 | |
| 220 | let fullResponse = "" |
| 221 | |
| 222 | // 处理流式响应 |
| 223 | for await (const chunk of stream) { |
| 224 | // 如果请求已被取消,停止处理 |
| 225 | if (abortControllerRef.current?.signal.aborted) { |
| 226 | break |
| 227 | } |
| 228 | |
| 229 | if (chunk) { |
| 230 | fullResponse += chunk |
| 231 | |
| 232 | // 更新助手消息的内容 |
| 233 | setMessages((prev) => |
| 234 | prev.map((msg) => |
| 235 | msg.id === assistantMessageId ? { ...msg, content: fullResponse, isLoading: false } : msg, |
| 236 | ), |
| 237 | ) |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | // 如果请求已被取消,不再继续后续处理 |
| 242 | if (abortControllerRef.current?.signal.aborted) { |
| 243 | return |
| 244 | } |
| 245 | |
| 246 | // 流式响应完成后,等待一小段时间确保前端更新 |
no test coverage detected