feat: 将系统提示词加入会话上下文中,系统提示词不会显示在前端。
This commit is contained in:
parent
38faeeb46d
commit
3471e8552f
|
|
@ -223,15 +223,25 @@ async function handleSend(
|
|||
await chatStore.createConversation();
|
||||
}
|
||||
|
||||
// 从当前会话中提取历史消息(用于上下文记忆),在添加新消息之前提取
|
||||
// 获取系统提示词(优先使用传入的,否则使用会话设置)
|
||||
const systemPrompt = options?.systemPrompt || currentConversation.value?.settings?.systemPrompt;
|
||||
|
||||
// 检查是否需要添加系统消息
|
||||
const existingMessages = currentConversation.value?.messages || [];
|
||||
const hasSystemMessage = existingMessages.some((m: any) => m.role === MessageRole.SYSTEM);
|
||||
|
||||
// 如果有系统提示词且对话中没有系统消息,添加系统消息
|
||||
if (systemPrompt && !hasSystemMessage) {
|
||||
await chatStore.addMessage(MessageRole.SYSTEM, {
|
||||
type: MessageType.TEXT,
|
||||
text: systemPrompt,
|
||||
});
|
||||
}
|
||||
|
||||
// 从当前会话中提取历史消息(用于上下文记忆),在添加新消息之前提取
|
||||
const updatedMessages = 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) // 过滤掉空消息
|
||||
const historyMessages = updatedMessages.filter((m: any) => m.content?.text) // 过滤掉空消息
|
||||
.slice(-(MAX_HISTORY_ROUNDS * 2))
|
||||
.map((m: any) => ({ role: m.role, content: m.content.text }));
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
<div ref="containerRef" class="message-list" @scroll="handleScroll">
|
||||
<!-- 欢迎界面 -->
|
||||
<WelcomeScreen
|
||||
v-if="messages.length === 0"
|
||||
v-if="visibleMessages.length === 0"
|
||||
@select="$emit('select-suggestion', $event)"
|
||||
/>
|
||||
|
||||
|
|
@ -12,12 +12,12 @@
|
|||
<div class="messages-wrapper">
|
||||
<TransitionGroup name="message">
|
||||
<MessageBubble
|
||||
v-for="(message, index) in messages"
|
||||
v-for="(message, index) in visibleMessages"
|
||||
:key="message.id"
|
||||
:message="message"
|
||||
:show-timestamp="showTimestamp"
|
||||
:compact="compact"
|
||||
:is-New="index === messages.length - 1"
|
||||
:is-New="index === visibleMessages.length - 1"
|
||||
@retry="$emit('retry', message.id)"
|
||||
@regenerate="$emit('regenerate', message.id)"
|
||||
@copy="handleCopy(message)"
|
||||
|
|
@ -62,12 +62,13 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, nextTick, onMounted } from "vue";
|
||||
import { ref, watch, nextTick, onMounted, computed } from "vue";
|
||||
import { useChatStore } from "@/stores/chat";
|
||||
import MessageBubble from "@/components/message/MessageBubble.vue";
|
||||
import WelcomeScreen from "./WelcomeScreen.vue";
|
||||
import { Bot, ChevronDown } from "@/components/icons";
|
||||
import type { Message, Attachment, VideoInfo, Suggestion } from "@/types/chat";
|
||||
import { MessageRole } from "@/types/chat";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
|
@ -83,6 +84,13 @@ const props = withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
// 过滤掉系统消息,不显示在前端
|
||||
const visibleMessages = computed(() => {
|
||||
return props.messages.filter(
|
||||
(message) => message.role !== MessageRole.SYSTEM
|
||||
);
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
retry: [messageId: string];
|
||||
regenerate: [messageId: string];
|
||||
|
|
@ -175,7 +183,7 @@ function handleDownloadFile(file: Attachment) {
|
|||
|
||||
// 监听消息变化
|
||||
watch(
|
||||
() => props.messages.length,
|
||||
() => visibleMessages.value.length,
|
||||
(newLen, oldLen) => {
|
||||
if (newLen > oldLen) {
|
||||
if (isAutoScrolling.value) {
|
||||
|
|
@ -191,7 +199,7 @@ watch(
|
|||
|
||||
// 监听最后一条消息的内容变化
|
||||
watch(
|
||||
() => props.messages[props.messages.length - 1]?.content.text,
|
||||
() => visibleMessages.value[visibleMessages.value.length - 1]?.content.text,
|
||||
() => {
|
||||
if (isAutoScrolling.value) {
|
||||
nextTick(() => {
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ async function textCopy(data: any) {
|
|||
/* 可折叠内容 */
|
||||
.thinking-content {
|
||||
max-height: 2000px;
|
||||
overflow: hidden;
|
||||
overflow: auto;
|
||||
transition:
|
||||
max-height 0.35s ease,
|
||||
opacity 0.25s ease;
|
||||
|
|
|
|||
|
|
@ -202,6 +202,7 @@ import FormSelect from "@/components/ui/FormSelect.vue";
|
|||
import { MessageSquare, X, Check, Trash2 } from "@/components/icons";
|
||||
import { chatApi } from "@/services/api.ts";
|
||||
import type { ConversationSettings } from "@/types/chat";
|
||||
import { MessageRole, MessageType } from "@/types/chat";
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
|
@ -359,6 +360,25 @@ function handleSave() {
|
|||
// 调用更新对话设置的方法
|
||||
chatStore.updateConversationSettings(conversation.value.id, convSettings);
|
||||
|
||||
// 如果系统提示词有变化,更新消息列表中的系统消息
|
||||
if (localSettings.value.systemPrompt) {
|
||||
const messages = conversation.value.messages || [];
|
||||
const systemMsgIndex = messages.findIndex((m: any) => m.role === MessageRole.SYSTEM);
|
||||
|
||||
if (systemMsgIndex >= 0) {
|
||||
// 更新已有的系统消息
|
||||
chatStore.updateMessage(messages[systemMsgIndex].id, {
|
||||
content: {
|
||||
type: MessageType.TEXT,
|
||||
text: localSettings.value.systemPrompt,
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// 添加新的系统消息(放在消息列表开头)
|
||||
chatStore.addSystemMessage(conversation.value.id, localSettings.value.systemPrompt);
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
// 显示成功提示
|
||||
|
|
|
|||
|
|
@ -121,21 +121,36 @@ class ChatApi {
|
|||
}
|
||||
|
||||
// 将前端简化的请求翻译为 OpenAI 兼容的规范请求体
|
||||
// 构建 messages 数组:system + 历史消息 + 当前用户消息
|
||||
const systemMessage = {
|
||||
role: "system",
|
||||
content:
|
||||
request.systemPrompt ||
|
||||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
|
||||
};
|
||||
const currentUserMessage = {
|
||||
role: "user",
|
||||
content: userContent,
|
||||
};
|
||||
const allMessages =
|
||||
request.history && request.history.length > 0
|
||||
? [systemMessage, ...request.history, currentUserMessage]
|
||||
: [systemMessage, currentUserMessage];
|
||||
// 检查历史消息中是否已有系统消息
|
||||
const historyHasSystem = request.history?.some((m) => m.role === "system");
|
||||
|
||||
// 构建 messages 数组
|
||||
let allMessages: Array<{ role: string; content: any }>;
|
||||
|
||||
if (request.history && request.history.length > 0) {
|
||||
// 如果历史中有系统消息,直接使用历史消息
|
||||
if (historyHasSystem) {
|
||||
allMessages = [...request.history, { role: "user", content: userContent }];
|
||||
} else {
|
||||
// 否则添加系统消息
|
||||
const systemMessage = {
|
||||
role: "system",
|
||||
content:
|
||||
request.systemPrompt ||
|
||||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
|
||||
};
|
||||
allMessages = [systemMessage, ...request.history, { role: "user", content: userContent }];
|
||||
}
|
||||
} else {
|
||||
// 没有历史消息,添加系统消息
|
||||
const systemMessage = {
|
||||
role: "system",
|
||||
content:
|
||||
request.systemPrompt ||
|
||||
"你是一个智能助手,可以分析用户发送的文字,文件或图片内容,并进行回答。",
|
||||
};
|
||||
allMessages = [systemMessage, { role: "user", content: userContent }];
|
||||
}
|
||||
|
||||
const openAiRequest = {
|
||||
model: request.model || "glm-4-flash",
|
||||
|
|
|
|||
|
|
@ -290,6 +290,38 @@ export const useChatStore = defineStore("chat", () => {
|
|||
return message;
|
||||
}
|
||||
|
||||
// 添加系统消息(放在消息列表开头)
|
||||
async function addSystemMessage(
|
||||
conversationId: string,
|
||||
systemPrompt: string
|
||||
): Promise<Message> {
|
||||
const conversation = conversations.value.find((c) => c.id === conversationId);
|
||||
if (!conversation) {
|
||||
throw new Error("Conversation not found");
|
||||
}
|
||||
|
||||
const message: Message = {
|
||||
id: generateId(),
|
||||
role: MessageRole.SYSTEM,
|
||||
content: { type: "text" as const, text: systemPrompt },
|
||||
timestamp: Date.now(),
|
||||
isStreaming: false,
|
||||
} as Message;
|
||||
|
||||
// 将系统消息插入到消息列表开头
|
||||
conversation.messages.unshift(message);
|
||||
conversation.updatedAt = Date.now();
|
||||
|
||||
// 异步保存
|
||||
try {
|
||||
await conversationApi.addMessage(conversationId, message);
|
||||
} catch (error) {
|
||||
console.error("Failed to save system message:", error);
|
||||
}
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
// 更新消息
|
||||
async function updateMessage(messageId: string, updates: Partial<Message>) {
|
||||
const conversation = currentConversation.value;
|
||||
|
|
@ -479,6 +511,7 @@ export const useChatStore = defineStore("chat", () => {
|
|||
renameConversation,
|
||||
updateConversationSettings,
|
||||
addMessage,
|
||||
addSystemMessage,
|
||||
updateMessage,
|
||||
updateMessageContent,
|
||||
saveConversation,
|
||||
|
|
|
|||
Loading…
Reference in New Issue