fix: 修复流式聊天错误处理并增加model_id参数

- 流式请求失败时不再隐藏用户消息,而是展示错误回复
- 在 ChatMessage.meta 类型中增加 error 字段用于标记错误消息
- 在 streamChat 函数中增加 model_id 参数
- 在 ModelOverrides 类型中增加 model_id 字段
main
sp mac bookpro 2605 2026-06-03 01:23:29 +08:00
parent 92ef2c38c8
commit dfab0f6d43
2 changed files with 53 additions and 31 deletions

View File

@ -91,19 +91,20 @@ export interface ToolCallTrace {
result: any;
}
export interface ChatMessage {
id: string;
role: 'user' | 'assistant';
content: string;
export interface ChatMessage {
id: string;
role: 'user' | 'assistant';
content: string;
reasoning?: string | null;
parentId?: string | null;
createdAt: number;
meta?: {
retrieved?: RetrievedSnippet[];
toolCalls?: ToolCallTrace[];
aborted?: boolean;
parentId?: string | null;
createdAt: number;
meta?: {
retrieved?: RetrievedSnippet[];
toolCalls?: ToolCallTrace[];
aborted?: boolean;
reasoning?: string;
} | null;
error?: string;
} | null;
}
export interface BranchInfo {
@ -700,33 +701,36 @@ export interface StreamEvents {
export interface ModelOverrides {
model?: string;
model_id?: string;
temperature?: number;
topP?: number;
maxTokens?: number;
}
export async function streamChat(
agentId: string,
content: string,
handlers: StreamEvents,
signal?: AbortSignal,
sessionId?: string,
export async function streamChat(
agentId: string,
content: string,
handlers: StreamEvents,
signal?: AbortSignal,
sessionId?: string,
model?: string,
imageUrls?: string[]
) {
const resp = await fetch(`https://api.hoyidata.com/aura/v1/chat/${agentId}/messages/stream`, {
method: 'POST',
modelId?: string,
imageUrls?: string[]
) {
const resp = await fetch(`https://api.hoyidata.com/aura/v1/chat/${agentId}/messages/stream`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream' },
body: JSON.stringify({
content,
sessionId,
body: JSON.stringify({
content,
sessionId,
model,
model_id: modelId,
imageUrls: imageUrls ?? []
}),
signal,
credentials: 'include'
});
return await consumeSSE(resp, handlers, signal);
}),
signal,
credentials: 'include'
});
return await consumeSSE(resp, handlers, signal);
}
/** 重新生成(开新分支);行为同 streamChat */

View File

@ -258,6 +258,7 @@ export default function ChatPage() {
abortRef.current = ctrl;
const model = overrides.model || parseAgentModels(agent?.model)[0] || '';
const modelId = overrides.model_id || '';
const attText = buildAttachmentsText();
const content = attText ? `${text}\n\n${attText}` : text;
@ -363,7 +364,15 @@ export default function ChatPage() {
},
onError: (errMsg) => {
msg.error('流式失败:' + errMsg);
setMessages((m) => (m || []).filter((x) => x.id !== tempUser.id));
// 创建错误消息作为助手回复,保留用户消息
const errorMessage: ChatMessage = {
id: 'error-' + Date.now(),
role: 'assistant',
content: `❌ 请求失败:${errMsg}`,
createdAt: Date.now(),
meta: { error: errMsg }
};
setMessages((m) => [...(m || []), errorMessage]);
setStreaming({
active: false,
reasoningText: '',
@ -378,13 +387,22 @@ export default function ChatPage() {
ctrl.signal,
sessionId || undefined,
model,
modelId,
imageUrls
);
} catch (e: any) {
if (e?.name !== 'AbortError') {
msg.error('请求失败:' + (e?.message ?? e));
// 创建错误消息作为助手回复,保留用户消息
const errorMessage: ChatMessage = {
id: 'error-' + Date.now(),
role: 'assistant',
content: `❌ 请求失败:${e?.message ?? String(e)}`,
createdAt: Date.now(),
meta: { error: e?.message ?? String(e) }
};
setMessages((m) => [...(m || []), errorMessage]);
}
setMessages((m) => (m || []).filter((x) => x.id !== tempUser.id));
setStreaming({
active: false,
reasoningText: '',