ai问片支持非流式响应

This commit is contained in:
mtvpls
2026-01-13 21:39:15 +08:00
parent 93688bb8da
commit 59e3685e65
5 changed files with 117 additions and 54 deletions
+55 -36
View File
@@ -152,63 +152,82 @@ export default function AIChatPanel({
body: JSON.stringify({
message: userMessage,
context,
history: messages.filter((m) => m.role !== 'assistant' || m.content !== welcomeMessage),
history: messages.filter((m) => m.role !== 'assistant' || m.content !== welcomeMessage),
}),
});
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
const errorMsg = errorData.error || errorData.details || `请求失败 (${response.status})`;
const errorMsg = errorData.error || errorData.details || `请求失败 (${response.status})`;
throw new Error(errorMsg);
}
// 处理流式响应
const reader = response.body?.getReader();
const decoder = new TextDecoder();
// 检查响应类型:流式(text/event-stream)或非流式(application/json)
const contentType = response.headers.get('content-type');
if (!reader) {
throw new Error('无法读取响应流');
}
if (contentType?.includes('text/event-stream')) {
// 处理流式响应
const reader = response.body?.getReader();
const decoder = new TextDecoder();
let assistantMessage = '';
if (!reader) {
throw new Error('无法读取响应流');
}
while (true) {
const { done, value } = await reader.read();
if (done) break;
let assistantMessage = '';
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n').filter((line) => line.trim() !== '');
while (true) {
const { done, value } = await reader.read();
if (done) break;
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
const chunk = decoder.decode(value, { stream: true });
const lines = chunk.split('\n').filter((line) => line.trim() !== '');
if (data === '[DONE]') {
break;
}
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = line.slice(6);
try {
const json = JSON.parse(data);
const text = json.text || '';
if (data === '[DONE]') {
break;
}
if (text) {
assistantMessage += text;
try {
const json = JSON.parse(data);
const text = json.text || '';
// 更新最后一条消息
setMessages((prev) => {
const newMessages = [...prev];
newMessages[newMessages.length - 1] = {
role: 'assistant',
content: assistantMessage,
};
return newMessages;
});
if (text) {
assistantMessage += text;
// 更新最后一条消息
setMessages((prev) => {
const newMessages = [...prev];
newMessages[newMessages.length - 1] = {
role: 'assistant',
content: assistantMessage,
};
return newMessages;
});
}
} catch (e) {
console.error('解析SSE数据失败:', e);
}
} catch (e) {
console.error('解析SSE数据失败:', e);
}
}
}
} else {
// 处理非流式响应
const data = await response.json();
const content = data.content || '';
// 更新最后一条消息为完整响应
setMessages((prev) => {
const newMessages = [...prev];
newMessages[newMessages.length - 1] = {
role: 'assistant',
content: content,
};
return newMessages;
});
}
} catch (error) {
console.error('发送消息失败:', error);