This commit is contained in:
2024-04-03 18:01:45 +08:00
parent 7a317ff749
commit 73dd6a21a7
3 changed files with 110 additions and 54 deletions

View File

@@ -1,28 +1,31 @@
<script lang="ts" setup>
import ChatItem from "~/components/aigc/chat/ChatItem.vue";
import Message from "~/components/aigc/chat/Message.vue";
import ChatItem from '~/components/aigc/chat/ChatItem.vue'
import Message from '~/components/aigc/chat/Message.vue'
import {
type Assistant,
type ChatMessage,
type ChatMessageId,
type ChatSession,
type ChatSessionId,
llmModels,
type ModelTag
} from "~/typings/llm";
import {useHistory} from "~/composables/useHistory";
import {uuidv4} from "@uniiem/uuid";
import {useLLM} from "~/composables/useLLM";
import {trimObject} from "@uniiem/object-trim";
import ModalAuthentication from "~/components/ModalAuthentication.vue";
type ModelTag,
} from '~/typings/llm'
import {useHistory} from '~/composables/useHistory'
import {uuidv4} from '@uniiem/uuid'
import {useLLM} from '~/composables/useLLM'
import {trimObject} from '@uniiem/object-trim'
import ModalAuthentication from '~/components/ModalAuthentication.vue'
import {useAsyncData} from '#app'
useHead({
title: '聊天 | XSH AI'
title: '聊天 | XSH AI',
})
const dayjs = useDayjs()
const toast = useToast()
const modal = useModal()
const loginState = useLoginState()
const {token, user, is_logged_in} = storeToRefs(loginState)
const historyStore = useHistory()
const {chatSessions} = storeToRefs(historyStore)
const {setChatSessions} = historyStore
@@ -35,14 +38,36 @@ const user_input = ref('')
const responding = ref(false)
const currentModel = ref<ModelTag>('spark3_5')
const modals = reactive({
modelSelect: false
modelSelect: false,
})
loginState.$subscribe((mutation, state) => {
console.log(mutation, state)
})
const {
data: assistantTemplates
} = await useAsyncData(
'App.Assistant_Template.GetList',
() => useFetchWrapped<
req.AssistantTemplateList & AuthedRequest, PagedData<Assistant>
>('App.Assistant_Template.GetList', {
user_id: loginState.user.id,
token: loginState.token as string,
page: 1,
perpage: 20,
}),
{
immediate: true,
watch: [is_logged_in],
},
)
/**
* 获取指定 ID 的会话数据
* @param chatSessionId
*/
const getSessionCopyById = (chatSessionId: ChatSessionId): ChatSession | undefined => chatSessions.value.find(s => s.id === chatSessionId);
const getSessionCopyById = (chatSessionId: ChatSessionId): ChatSession | undefined => chatSessions.value.find(s => s.id === chatSessionId)
/**
* 切换当前会话
* @param chatSessionId 指定会话 ID不传则切换到列表中第一个会话
@@ -95,7 +120,8 @@ const handleClickCreateSession = () => {
])
// 切换到新的会话
selectCurrentSessionId(sessionId)
modals.modelSelect = true
// TODO: Model or Assistant Selection
// modals.modelSelect = true
nextTick(() => {
insetMessage({
id: uuidv4(),
@@ -112,12 +138,12 @@ const handleClickCreateSession = () => {
const handleClickSend = (event: any) => {
if (!loginState.is_logged_in) {
modal.open(ModalAuthentication)
return;
return
}
if (event.ctrlKey) {
return;
return
}
if (responding.value) return;
if (responding.value) return
if (!user_input.value) return
if (!currentSessionId.value) {
toast.add({
@@ -126,7 +152,7 @@ const handleClickSend = (event: any) => {
color: 'red',
icon: 'i-tabler-circle-x',
})
return;
return
}
// 插入用户消息
insetMessage({
@@ -146,10 +172,10 @@ const handleClickSend = (event: any) => {
})
// 请求模型回复
const trimmedMessages = trimObject(getMessages(), 2000, {
keys: ['content']
keys: ['content'],
})
useLLM(trimmedMessages, {
modelTag: currentModel.value
modelTag: currentModel.value,
}).then(reply => {
modifyMessageContent(assistantReplyId, reply)
}).catch(err => {
@@ -173,8 +199,8 @@ const insetMessage = (message: ChatMessage): ChatMessageId => {
...s,
messages: [
...s.messages,
message
]
message,
],
} : s))
scrollToMessageListBottom()
return message.id
@@ -186,7 +212,7 @@ const modifyMessageContent = (
messageId: ChatMessageId,
content: string,
interrupted: boolean = false,
updateTime: boolean = true
updateTime: boolean = true,
) => {
setChatSessions(chatSessions.value.map(s => s.id === currentSessionId.value ? {
...s,
@@ -195,7 +221,7 @@ const modifyMessageContent = (
content,
interrupted,
create_at: updateTime ? dayjs().unix() : m.create_at,
} : m)
} : m),
} : s))
scrollToMessageListBottom()
}
@@ -248,7 +274,8 @@ onMounted(() => {
</div>
</div>
<div class="h-[calc(100vh-4rem)] bg-white dark:bg-neutral-900 flex-1 flex flex-col">
<div class="w-full p-4 bg-neutral-50 dark:bg-neutral-800/50 border-b dark:border-neutral-700/50 flex items-center gap-2">
<div
class="w-full p-4 bg-neutral-50 dark:bg-neutral-800/50 border-b dark:border-neutral-700/50 flex items-center gap-2">
<UButton
class="md:hidden"
color="black"
@@ -269,16 +296,24 @@ onMounted(() => {
/>
</TransitionGroup>
</div>
<pre>{{assistantTemplates}}</pre>
</div>
<ClientOnly>
<div
class="w-full p-4 pt-2 flex flex-col gap-2 bg-neutral-50 dark:bg-neutral-800/50 border-t dark:border-neutral-700/50">
<div class="flex items-center gap-2 overflow-auto overflow-y-hidden">
<button class="chat-option-btn" @click="modals.modelSelect = true">
<Icon name="tabler:robot-face"/>
<Icon name="tabler:box"/>
<span class="text-xs">
{{ llmModels.find(m => m.tag === currentModel)?.name.toUpperCase() || '模型' }}
</span>
</button>
<button class="chat-option-btn" @click="modals.modelSelect = true">
<Icon name="tabler:robot-face"/>
<span class="text-xs">
助手
</span>
</button>
</div>
<div class="relative">
<UTextarea
@@ -303,6 +338,7 @@ onMounted(() => {
</UButton>
</div>
</div>
</ClientOnly>
</div>
<!-- Modals -->

View File

@@ -14,10 +14,25 @@ export interface LLMModal {
endpoint: string
}
export interface Assistant {
id: number;
user_id: number;
create_time: number;
tpl_name: string;
types: string;
des: string;
input_tpl: string;
role: string;
target: string;
style: string;
demand: string;
}
export namespace LLMSpark {
export interface request {
prompt: string
}
export interface response {
request_msg?: string
request_fail?: {

View File

@@ -55,6 +55,11 @@ namespace req {
file_size: number
}
}
interface AssistantTemplateList {
page: number
perpage: number
}
}
namespace resp {