feat(context): 新增上下文记忆功能,支持在对话中保持用户输入上下文信息

This commit is contained in:
肖应宇 2026-03-05 11:41:32 +08:00 committed by SuperManTouX
parent 87efcdd296
commit a289db56c7
2 changed files with 39 additions and 13 deletions

View File

@ -152,6 +152,15 @@ async function handleSend(text: string, attachments: Attachment[], options?: { d
chatStore.createConversation(); chatStore.createConversation();
} }
//
const existingMessages = currentConversation.value?.messages || [];
const MAX_HISTORY_ROUNDS = 20; // 20 40
const historyMessages = existingMessages
.filter((m: any) => m.role === MessageRole.USER || m.role === MessageRole.ASSISTANT)
.filter((m: any) => m.content?.text) //
.slice(-(MAX_HISTORY_ROUNDS * 2))
.map((m: any) => ({ role: m.role, content: m.content.text }));
// //
chatStore.addMessage(MessageRole.USER, { chatStore.addMessage(MessageRole.USER, {
type: MessageType.TEXT, type: MessageType.TEXT,
@ -189,9 +198,10 @@ async function handleSend(text: string, attachments: Attachment[], options?: { d
message: text, message: text,
conversationId: currentConversation.value?.id || "", conversationId: currentConversation.value?.id || "",
images: imageUrls, images: imageUrls,
files: fileUrls, // URL files: fileUrls,
model: settings.value.defaultModel, model: settings.value.defaultModel,
stream: true, stream: true,
history: historyMessages,
deepSearch: options?.deepSearch, deepSearch: options?.deepSearch,
webSearch: options?.webSearch, webSearch: options?.webSearch,
deepThinking: options?.deepThinking, deepThinking: options?.deepThinking,
@ -259,6 +269,15 @@ async function handleRetry(messageId: string) {
const userMessage = messages.value[messageIndex - 1]; const userMessage = messages.value[messageIndex - 1];
if (userMessage.role !== MessageRole.USER) return; if (userMessage.role !== MessageRole.USER) return;
//
const MAX_HISTORY_ROUNDS = 20;
const priorMessages = messages.value
.slice(0, messageIndex - 1) // user assistant
.filter((m: any) => m.role === MessageRole.USER || m.role === MessageRole.ASSISTANT)
.filter((m: any) => m.content?.text)
.slice(-(MAX_HISTORY_ROUNDS * 2))
.map((m: any) => ({ role: m.role, content: m.content.text }));
// //
chatStore.updateMessage(messageId, { chatStore.updateMessage(messageId, {
isError: false, isError: false,
@ -279,6 +298,7 @@ async function handleRetry(messageId: string) {
conversationId: currentConversation.value?.id, conversationId: currentConversation.value?.id,
model: settings.value.defaultModel, model: settings.value.defaultModel,
stream: true, stream: true,
history: priorMessages,
}, },
abortController.value.signal, abortController.value.signal,
); );

View File

@ -40,6 +40,8 @@ export interface ChatRequest {
maxTokens?: number; maxTokens?: number;
systemPrompt?: string; systemPrompt?: string;
stream?: boolean; stream?: boolean;
// 历史对话消息(用于上下文记忆)
history?: { role: string; content: string }[];
// 扩展选项 // 扩展选项
deepSearch?: boolean; deepSearch?: boolean;
webSearch?: boolean; webSearch?: boolean;
@ -107,22 +109,26 @@ class ChatApi {
} }
// 将前端简化的请求翻译为 OpenAI 兼容的规范请求体 // 将前端简化的请求翻译为 OpenAI 兼容的规范请求体
const openAiRequest = { // 构建 messages 数组system + 历史消息 + 当前用户消息
model: request.model || "glm-4-flash", // 可能需要指定支持视觉的模型 const systemMessage = {
messages: [
{
role: "system", role: "system",
content: request.systemPrompt || "你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。", content: request.systemPrompt || "你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
}, };
{ const currentUserMessage = {
role: "user", role: "user",
content: userContent, content: userContent,
}, };
], const allMessages = request.history && request.history.length > 0
? [systemMessage, ...request.history, currentUserMessage]
: [systemMessage, currentUserMessage];
const openAiRequest = {
model: request.model || "glm-4-flash",
messages: allMessages,
stream: true, stream: true,
temperature: request.temperature, temperature: request.temperature,
max_tokens: request.maxTokens, max_tokens: request.maxTokens,
files: request.files || [], // 传递文件 URL 列表给后端 files: request.files || [],
// 扩展参数传递给我们的 Python 后端进行特殊处理 // 扩展参数传递给我们的 Python 后端进行特殊处理
deepSearch: request.deepSearch, deepSearch: request.deepSearch,
webSearch: request.webSearch, webSearch: request.webSearch,