fix: propagate real message IDs via SSE and fix regenerate model parameter
- Add message_id and user_message_id to SSE done events so frontend can replace temp IDs with real DB IDs, fixing "消息不存在" on regenerate - Replace Body(default=None) with RegenerateRequest Pydantic model for proper JSON body parsing, fixing 422 Unprocessable Content - Frontend always sends model in regenerate request body - Pass selected model through message-item → regenerateMessage chain - Various UI refinements to chat sidebar, quick questions, and layout Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+31
-27
@@ -28,7 +28,7 @@ interface ChatActions {
|
||||
addMessage: (message: ChatMessage) => void;
|
||||
updateMessage: (messageId: number, content: string) => void;
|
||||
editMessage: (messageId: number, newContent: string) => Promise<void>;
|
||||
regenerateMessage: (messageId: number) => Promise<void>;
|
||||
regenerateMessage: (messageId: number, model?: string) => Promise<void>;
|
||||
feedbackMessage: (messageId: number, feedback: "like" | "dislike") => Promise<void>;
|
||||
stopGeneration: () => void;
|
||||
|
||||
@@ -228,12 +228,6 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
// 创建新的 AbortController
|
||||
const abortController = new AbortController();
|
||||
|
||||
console.log("[DEBUG-CHAT] 开始流式发送:", {
|
||||
message: message,
|
||||
sessionId: currentSession.id,
|
||||
knowledgeBaseIds: knowledgeBaseIds
|
||||
});
|
||||
|
||||
set({ isStreaming: true, error: null, abortController });
|
||||
|
||||
// 添加用户消息
|
||||
@@ -299,8 +293,7 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
// 处理内容chunk
|
||||
chunkCount++;
|
||||
totalChars += data.content.length;
|
||||
console.log(`[DEBUG-STREAM] 接收并显示chunk ${chunkCount}:`, data.content);
|
||||
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
set((state) => ({
|
||||
messages: state.messages.map(msg =>
|
||||
@@ -315,8 +308,7 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
// 向后兼容:纯文本chunk
|
||||
chunkCount++;
|
||||
totalChars += chunk.length;
|
||||
console.log(`[DEBUG-STREAM] 接收并显示chunk ${chunkCount}:`, chunk);
|
||||
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
set((state) => ({
|
||||
messages: state.messages.map(msg =>
|
||||
@@ -328,17 +320,30 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
});
|
||||
}
|
||||
},
|
||||
(sessionId: number) => {
|
||||
// 流式完成,直接处理
|
||||
console.log(`[DEBUG-STREAM] 流式完成 - 总chunk数: ${chunkCount}, 总字符数: ${totalChars}`);
|
||||
set({ isStreaming: false, abortController: null });
|
||||
|
||||
(sessionId: number, messageId?: number, userMessageId?: number) => {
|
||||
if (messageId) {
|
||||
set((state) => ({
|
||||
messages: state.messages.map(msg => {
|
||||
if (msg.id === assistantMessage.id) return { ...msg, id: messageId };
|
||||
if (userMessageId && msg.id === userMessage.id) return { ...msg, id: userMessageId };
|
||||
return msg;
|
||||
}),
|
||||
isStreaming: false,
|
||||
abortController: null,
|
||||
}));
|
||||
} else {
|
||||
const { currentSession } = get();
|
||||
if (currentSession) {
|
||||
get().loadMessages(currentSession.id);
|
||||
}
|
||||
set({ isStreaming: false, abortController: null });
|
||||
}
|
||||
|
||||
// 刷新会话列表以确保新会话显示在顶部
|
||||
get().loadSessions();
|
||||
},
|
||||
(error: string) => {
|
||||
// 流式错误
|
||||
console.log("[DEBUG-STREAM] 流式错误:", error);
|
||||
set({ error, isStreaming: false, abortController: null });
|
||||
},
|
||||
undefined, // onStatus
|
||||
@@ -409,20 +414,20 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
}
|
||||
},
|
||||
|
||||
// 重新生成消息
|
||||
regenerateMessage: async (messageId: number) => {
|
||||
// 重新生成消息(支持 assistant 消息 ID)
|
||||
regenerateMessage: async (messageId: number, model?: string) => {
|
||||
try {
|
||||
set({ isLoading: true, error: null });
|
||||
const response = await chatAPI.regenerateMessage(messageId);
|
||||
|
||||
// 删除该消息之后的所有消息
|
||||
const response = await chatAPI.regenerateMessage(messageId, model);
|
||||
|
||||
// 找到该消息,删除它及之后的所有消息
|
||||
const messageIndex = get().messages.findIndex(msg => msg.id === messageId);
|
||||
if (messageIndex !== -1) {
|
||||
set((state) => ({
|
||||
messages: state.messages.slice(0, messageIndex + 1),
|
||||
messages: state.messages.slice(0, messageIndex),
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
// 添加新的助手回复
|
||||
const newMessage: ChatMessage = {
|
||||
id: response.new_message_id,
|
||||
@@ -430,7 +435,7 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
content: response.content,
|
||||
created_at: new Date().toISOString(),
|
||||
};
|
||||
|
||||
|
||||
set((state) => ({
|
||||
messages: [...state.messages, newMessage],
|
||||
isLoading: false,
|
||||
@@ -465,9 +470,8 @@ export const useChatStore = create<ChatStore>((set, get) => ({
|
||||
// 如果存在 AbortController,调用 abort 中止请求
|
||||
if (abortController) {
|
||||
abortController.abort();
|
||||
console.log("[DEBUG-STOP] 已中止流式请求");
|
||||
}
|
||||
|
||||
|
||||
// 清理状态
|
||||
set({ isStreaming: false, abortController: null });
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user