diff --git a/components/aigc/chat/Message.vue b/components/aigc/chat/Message.vue index b62d448..c6b5b30 100644 --- a/components/aigc/chat/Message.vue +++ b/components/aigc/chat/Message.vue @@ -1,13 +1,13 @@ + + + + \ No newline at end of file diff --git a/pages/aigc/chat/index.vue b/pages/aigc/chat/index.vue index 60c54be..00c2dac 100644 --- a/pages/aigc/chat/index.vue +++ b/pages/aigc/chat/index.vue @@ -15,7 +15,7 @@ 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' +import NewSessionScreen from '~/components/aigc/chat/NewSessionScreen.vue' useHead({ title: '聊天 | XSH AI', @@ -25,7 +25,6 @@ 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 @@ -37,32 +36,13 @@ const showSidebar = ref(false) const user_input = ref('') const responding = ref(false) const currentModel = ref('spark3_5') +const currentAssistant = computed(() => getSessionCopyById(currentSessionId.value || '')?.assistant || null) const modals = reactive({ modelSelect: false, + assistantSelect: false, + newSessionScreen: false, }) -loginState.$subscribe((mutation, state) => { - console.log(mutation, state) -}) - -const { - data: assistantTemplates -} = await useAsyncData( - 'App.Assistant_Template.GetList', - () => useFetchWrapped< - req.AssistantTemplateList & AuthedRequest, PagedData - >('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 @@ -98,39 +78,79 @@ const selectCurrentSessionId = (chatSessionId?: ChatSessionId) => { } nextTick(() => { showSidebar.value = false + modals.newSessionScreen = false scrollToMessageListBottom() }) } /** - * 处理新建会话操作 + * 创建新会话处理函数 + * @param assistant 指定助手,不传或空值则不指定助手 */ -const handleClickCreateSession = () => { +const createSession = (assistant: Assistant | null) => { // 生成一个新的会话 ID const sessionId = uuidv4() + // 新会话数据 + const newChat = !!assistant ? { + id: sessionId, + subject: '新对话', + messages: [], + create_at: dayjs().unix(), + assistant, + } : { + id: sessionId, + subject: '新对话', + messages: [], + create_at: dayjs().unix(), + } // 插入新会话数据 setChatSessions([ - { - id: sessionId, - subject: '新对话', - messages: [], - create_at: dayjs().unix(), - }, + newChat, ...chatSessions.value, ]) // 切换到新的会话 selectCurrentSessionId(sessionId) - // TODO: Model or Assistant Selection - // modals.modelSelect = true + // 关闭新建会话屏幕 + modals.newSessionScreen = false nextTick(() => { - insetMessage({ - id: uuidv4(), - role: 'assistant', - content: '你好,有什么可以帮助你的吗?', - }) + if (!!currentAssistant.value) { + insetMessage({ + id: uuidv4(), + role: 'system', + content: currentAssistant.value?.role || '', + preset: true, + }) + insetMessage({ + id: uuidv4(), + role: 'user', + content: `${currentAssistant.value?.target},${currentAssistant.value?.demand}`, + preset: true, + }) + insetMessage({ + id: uuidv4(), + role: 'assistant', + content: currentAssistant.value?.input_tpl || '', + preset: true, + }) + } else { + insetMessage({ + id: uuidv4(), + role: 'assistant', + content: '你好,有什么可以帮助你的吗?', + preset: true, + }) + } }) } +/** + * 处理点击新建会话按钮事件 + */ +const handleClickCreateSession = () => { + showSidebar.value = false + modals.newSessionScreen = true +} + /** * 处理发送消息操作 * @param event @@ -273,83 +293,98 @@ onMounted(() => { -
-
- - -

{{ getSessionCopyById(currentSessionId!)?.subject || '新对话' }}

-
-
-
- - - -
-
{{assistantTemplates}}
-
- +
+ + +
-
- - -
-
- + v-else + class="w-full h-full flex flex-col" + > +
- 发送 +

{{ getSessionCopyById(currentSessionId!)?.subject || '新对话' }}

+
+
+ + + +
+
+ +
+
+ + +
+
+ + + 发送 + +
+
+
- + +
- + -
{ class="flex flex-col gap-2 justify-center items-center w-full aspect-[1/1] border-2 rounded-xl cursor-pointer transition duration-150 select-none" :class="llm.tag === currentModel ? 'border-primary shadow-xl bg-primary text-white' : 'dark:border-neutral-800 bg-white dark:bg-black shadow-card'" > - +

{{ llm.name || 'unknown' }}

{{ llm.description }}

-
+
diff --git a/typings/llm.ts b/typings/llm.ts index 20e4af3..6146946 100644 --- a/typings/llm.ts +++ b/typings/llm.ts @@ -76,6 +76,7 @@ export interface ChatSession { create_at: number messages: ChatMessage[] last_input?: string + assistant?: Assistant } export type MessageRole = 'user' | 'assistant' | 'system' @@ -84,6 +85,7 @@ export interface ChatMessage { id: ChatMessageId role: MessageRole content: string + preset?: boolean create_at?: number interrupted?: boolean } diff --git a/typings/types.d.ts b/typings/types.d.ts index d055640..41149c7 100644 --- a/typings/types.d.ts +++ b/typings/types.d.ts @@ -11,7 +11,10 @@ interface BaseResponse { // TODO: PagedData schema interface PagedData { - + total: number + page: number + perpage: number + items: T[] } interface UserSchema {