feat: 对接 Spark 大模型

This commit is contained in:
2024-04-01 17:03:03 +08:00
parent d20b518f5b
commit 3ded5f8e7a
12 changed files with 328 additions and 67 deletions

View File

@@ -1,9 +1,10 @@
<script lang="ts" setup>
import ChatItem from "~/components/aigc/chat/ChatItem.vue";
import type {ChatMessage, ChatMessageId, ChatSessionId} from "~/components/aigc/chat";
import Message from "~/components/aigc/chat/Message.vue";
import {useIdGenerator} from "~/composables/useIdGenerator";
import type {ChatMessage, ChatMessageId, ChatSessionId} from "~/typings/llm";
import {useHistory} from "~/composables/useHistory";
import {uuidv4} from "@uniiem/uuid";
import {useLLM} from "~/composables/useLLM";
useHead({
title: '聊天 | XSH AI'
@@ -11,7 +12,6 @@ useHead({
const dayjs = useDayjs()
const toast = useToast()
const {generateUUID} = useIdGenerator()
const historyStore = useHistory()
const {chatSessions} = storeToRefs(historyStore)
const {setChatSessions} = historyStore
@@ -23,7 +23,15 @@ const messagesWrapperRef = ref<HTMLDivElement | null>(null)
const user_input = ref('')
const responding = ref(false)
/**
* 获取指定 ID 的会话数据
* @param chatSessionId
*/
const getSessionCopyById = (chatSessionId: ChatSessionId) => chatSessions.value.find(s => s.id === chatSessionId);
/**
* 切换当前会话
* @param chatSessionId 指定会话 ID不传则切换到列表中第一个会话
*/
const selectCurrentSessionId = (chatSessionId?: ChatSessionId) => {
if (chatSessions.value.length > 0) {
if (chatSessionId) { // 切换到指定 ID
@@ -48,11 +56,17 @@ const selectCurrentSessionId = (chatSessionId?: ChatSessionId) => {
} else {
handleClickCreateSession()
}
nextTick(() => {
scrollToMessageListBottom()
})
}
/**
* 处理新建会话操作
*/
const handleClickCreateSession = () => {
// 生成一个新的会话 ID
const sessionId = generateUUID()
const sessionId = uuidv4()
// 插入新会话数据
setChatSessions([
{
@@ -67,6 +81,10 @@ const handleClickCreateSession = () => {
selectCurrentSessionId(sessionId)
}
/**
* 处理发送消息操作
* @param event
*/
const handleClickSend = (event: any) => {
if (event.ctrlKey) {
return;
@@ -84,7 +102,7 @@ const handleClickSend = (event: any) => {
}
// 插入用户消息
insetMessage({
id: generateUUID(),
id: uuidv4(),
role: 'user',
content: user_input.value,
create_at: dayjs().unix(),
@@ -94,16 +112,20 @@ const handleClickSend = (event: any) => {
responding.value = true
// 插入空助手消息(加载状态)
const assistantReplyId = insetMessage({
id: generateUUID(),
id: uuidv4(),
role: 'assistant',
content: '',
create_at: dayjs().unix(),
})
// mock
setTimeout(() => {
modifyMessageContent(assistantReplyId, '草,走,忽略!ጿ ኈ ቼ ዽ ጿ')
// 请求模型回复
useLLM(getMessages(), {
modelTag: 'spark3_5'
}).then(reply => {
modifyMessageContent(assistantReplyId, reply)
}).catch(err => {
modifyMessageContent(assistantReplyId, err, true)
}).finally(() => {
responding.value = false
}, 1000)
})
}
const scrollToMessageListBottom = () => {
@@ -127,12 +149,21 @@ const insetMessage = (message: ChatMessage): ChatMessageId => {
return message.id
}
const modifyMessageContent = (messageId: ChatMessageId, content: string) => {
const getMessages = () => getSessionCopyById(currentSessionId.value!)?.messages || []
const modifyMessageContent = (
messageId: ChatMessageId,
content: string,
interrupted: boolean = false,
updateTime: boolean = true
) => {
setChatSessions(chatSessions.value.map(s => s.id === currentSessionId.value ? {
...s,
messages: s.messages.map(m => m.id === messageId ? {
...m,
content,
interrupted,
create_at: updateTime ? dayjs().unix() : m.create_at,
} : m)
} : s))
scrollToMessageListBottom()
@@ -188,7 +219,7 @@ onMounted(() => {
<div class="flex flex-col gap-8 px-4 py-8">
<TransitionGroup name="message">
<Message
v-for="message in getSessionCopyById(currentSessionId!)?.messages || []"
v-for="message in getMessages() || []"
:message="message"
:key="message.id"
/>
@@ -234,8 +265,4 @@ onMounted(() => {
.message-enter-from {
@apply translate-y-4 opacity-0;
}
.message-leave-to {
@apply -translate-y-4 opacity-0;
}
</style>