feat(ui): added core system error message

Signed-off-by: Neko Ayaka <neko@ayaka.moe>
This commit is contained in:
Neko Ayaka
2025-03-04 00:55:06 +08:00
parent 0528239bfd
commit f52b8d85ac
12 changed files with 287 additions and 124 deletions
@@ -79,6 +79,7 @@ stage:
character-name:
airi: Airi
you: You
core-system: Core System
tabs:
chat: Chat
clothes: Clothes
@@ -66,3 +66,18 @@ stage:
select-a-model: 选择一个模型
select-a-voice: 选择一个声线
waiting: 等待中
chat:
message:
character-name:
airi: Airi
you:
core-system: 核心系统
tabs:
chat: 聊天
clothes: 换装
custom: 自定义
operations:
load-models: 加载推理模型
load-models-status:
loading: 加载中
ready: 已就绪
@@ -7,7 +7,7 @@ import { nextTick, ref } from 'vue'
const chatHistoryRef = ref<HTMLDivElement>()
const { messages } = storeToRefs(useChatStore())
const { messages, sending } = storeToRefs(useChatStore())
const bounding = useElementBounding(chatHistoryRef, { immediate: true, windowScroll: true, windowResize: true })
const { y: chatHistoryContainerY } = useScroll(chatHistoryRef)
@@ -34,38 +34,58 @@ onTokenLiteral(async () => {
<template>
<div py="1" flex="~ col" rounded="lg" overflow-hidden>
<div flex-1 /> <!-- spacer -->
<div ref="chatHistoryRef" v-auto-animate max-h="30vh" flex="~ col" scrollbar="~ w-2 track-color-transparent thumb-color-pink-300 rounded" h-full w-full overflow-scroll>
<div
ref="chatHistoryRef" v-auto-animate max-h="30vh" flex="~ col"
scrollbar="~ w-2 track-color-transparent thumb-color-pink-300 rounded" h-full w-full overflow-scroll
>
<div flex-1 /> <!-- spacer -->
<div v-for="(message, index) in messages" :key="index" mb-2>
<div v-if="message.role === 'error'" flex mr="12">
<div
flex="~ col" border="4 solid violet-200/50 dark:violet-500/50" shadow="md violet-200/50 dark:none"
min-w-20 rounded-lg px-2 py-1 h="unset <sm:fit" bg="<md:violet-500/25"
>
<div flex="~ row" gap-2>
<div flex-1>
<span text-xs text="violet-400/90 dark:violet-600/90" font-semibold class="inline <sm:hidden">{{
$t('stage.chat.message.character-name.core-system') }}</span>
</div>
<div i-solar:danger-triangle-bold-duotone text-violet-500 />
</div>
<div v-if="sending" i-eos-icons:three-dots-loading />
<div
v-else class="markdown-content text-violet-500" text="base <sm:xs"
v-html="process(message.content as string)"
/>
</div>
</div>
<div v-if="message.role === 'assistant'" flex mr="12">
<div
flex="~ col"
border="4 solid pink-200"
shadow="md pink-200/50"
min-w-20 rounded-lg px-2 py-1
h="fit"
flex="~ col" border="4 solid pink-200" shadow="md pink-200/50" min-w-20 rounded-lg px-2 py-1 h="fit"
bg="pink-100"
>
<div>
<span text-xs text="pink-400/90" font-semibold class="inline hidden">Airi</span>
</div>
<div v-if="message.content" class="markdown-content" text="xs pink-400" v-html="process(message.content as string)" />
<div
v-if="message.content" class="markdown-content" text="xs pink-400"
v-html="process(message.content as string)"
/>
<div v-else i-eos-icons:three-dots-loading />
</div>
</div>
<div v-else-if="message.role === 'user'" flex="~">
<div
flex="~ col"
border="4 solid cyan-200"
shadow="md cyan-200/50"
px="2"
h="fit" min-w-20 rounded-lg px-2 py-1
bg="cyan-100"
flex="~ col" border="4 solid cyan-200" shadow="md cyan-200/50" px="2" h="fit" min-w-20 rounded-lg px-2
py-1 bg="cyan-100"
>
<div>
<span text-xs text="cyan-600/90" font-semibold class="hidden">You</span>
</div>
<div v-if="message.content" class="markdown-content" text="xs cyan-600" v-html="process(message.content as string)" />
<div
v-if="message.content" class="markdown-content" text="xs cyan-600"
v-html="process(message.content as string)"
/>
<div v-else />
</div>
</div>
@@ -15,6 +15,7 @@ const listening = ref(false)
// const { selectedAudioDevice, isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
const { isAudioInputOn, selectedAudioDeviceId } = storeToRefs(useSettings())
const { send, onAfterSend } = useChatStore()
const { messages } = storeToRefs(useChatStore())
const { t } = useI18n()
async function handleSend() {
@@ -22,7 +23,16 @@ async function handleSend() {
return
}
await send(messageInput.value)
try {
await send(messageInput.value)
}
catch (error) {
messages.value.pop()
messages.value.push({
role: 'error',
content: (error as Error).message,
})
}
}
const { destroy, start } = useMicVAD(selectedAudioDeviceId, {