refactor(*): cleaner provider design, simplified chat store

This commit is contained in:
Neko Ayaka
2026-08-08 01:34:44 +08:00
parent 5f1c52ec52
commit eb35c4d66a
157 changed files with 5343 additions and 5980 deletions
@@ -3,7 +3,7 @@ import type { ChatHistoryItem } from '@proj-airi/stage-ui/types/chat'
import { ChatHistory } from '@proj-airi/stage-ui/components'
import { useAnalytics } from '@proj-airi/stage-ui/composables/use-analytics'
import { useChatOrchestratorStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatSessionStore } from '@proj-airi/stage-ui/stores/chat/session-store'
import { useChatStreamStore } from '@proj-airi/stage-ui/stores/chat/stream-store'
import { useDeferredMount } from '@proj-airi/ui'
@@ -17,7 +17,7 @@ import ChatContainer from '../Widgets/ChatContainer.vue'
import { useChatToolCallRerun } from '../../composables/useChatToolCallRerun'
const { isReady } = useDeferredMount()
const { sending } = storeToRefs(useChatOrchestratorStore())
const { sending } = storeToRefs(useChatStore())
const { messages } = storeToRefs(useChatSessionStore())
const { streamingMessage } = storeToRefs(useChatStreamStore())
@@ -8,13 +8,14 @@ import { ChatHistory, HearingConfigDialog } from '@proj-airi/stage-ui/components
import { ChatSessionsDrawer } from '@proj-airi/stage-ui/components/scenarios/chat'
import { useAnalytics, useAudioAnalyzer } from '@proj-airi/stage-ui/composables'
import { useAudioContext } from '@proj-airi/stage-ui/stores/audio'
import { useChatOrchestratorStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatMaintenanceStore } from '@proj-airi/stage-ui/stores/chat/maintenance'
import { useChatSessionStore } from '@proj-airi/stage-ui/stores/chat/session-store'
import { useChatStreamStore } from '@proj-airi/stage-ui/stores/chat/stream-store'
import { useL2dViewControl } from '@proj-airi/stage-ui/stores/live2d'
import { useConsciousnessStore } from '@proj-airi/stage-ui/stores/modules/consciousness'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { useProviderConfigStore } from '@proj-airi/stage-ui/stores/providers/config'
import { useProviderStore } from '@proj-airi/stage-ui/stores/providers/provider'
import { useSettings, useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings'
import { BasicTextarea, useTheme } from '@proj-airi/ui'
import { useResizeObserver, useScreenSafeArea } from '@vueuse/core'
@@ -33,7 +34,7 @@ import { useStopSpeakingButton } from '../../composables/useStopSpeakingButton'
import { BackgroundDialogPicker } from '../Backgrounds'
const { isDark, toggleDark } = useTheme()
const chatOrchestrator = useChatOrchestratorStore()
const chatOrchestrator = useChatStore()
const chatSession = useChatSessionStore()
const chatStream = useChatStreamStore()
const { cleanupMessages } = useChatMaintenanceStore()
@@ -68,7 +69,8 @@ const backgroundDialogOpen = ref(false)
const sessionsDrawerOpen = ref(false)
const screenSafeArea = useScreenSafeArea()
const providersStore = useProvidersStore()
const providersStore = useProviderStore()
const providerStore = useProviderConfigStore()
const { activeProvider, activeModel } = storeToRefs(useConsciousnessStore())
useResizeObserver(document.documentElement, () => screenSafeArea.update())
@@ -112,7 +114,7 @@ async function handleSend() {
messageInput.value = ''
try {
const providerConfig = providersStore.getProviderConfig(activeProvider.value)
const providerConfig = providerStore.getProviderConfig(activeProvider.value)
await ingest(textToSend, {
chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider,
@@ -6,10 +6,11 @@ import { isStageTamagotchi } from '@proj-airi/stage-shared'
import { HearingConfig } from '@proj-airi/stage-ui/components/scenarios/dialogs/audio-input/index'
import { useAudioAnalyzer } from '@proj-airi/stage-ui/composables'
import { useAudioContext } from '@proj-airi/stage-ui/stores/audio'
import { useChatOrchestratorStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatStore } from '@proj-airi/stage-ui/stores/chat'
import { useChatSessionStore } from '@proj-airi/stage-ui/stores/chat/session-store'
import { useConsciousnessStore } from '@proj-airi/stage-ui/stores/modules/consciousness'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { useProviderConfigStore } from '@proj-airi/stage-ui/stores/providers/config'
import { useProviderStore } from '@proj-airi/stage-ui/stores/providers/provider'
import { useSettings, useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings'
import { BasicTextarea } from '@proj-airi/ui'
import { useLocalStorage } from '@vueuse/core'
@@ -33,13 +34,15 @@ type SendMode = (typeof SEND_MODES)[number]
const sendMode = useLocalStorage<SendMode>('ui/chat/settings/send-mode', 'enter')
const lastEnterTime = ref(0)
const providersStore = useProvidersStore()
const providersStore = useProviderStore()
const providerStore = useProviderConfigStore()
const { activeProvider, activeModel } = storeToRefs(useConsciousnessStore())
const { themeColorsHueDynamic } = storeToRefs(useSettings())
const { askPermission } = useSettingsAudioDevice()
const { enabled, stream } = storeToRefs(useSettingsAudioDevice())
const chatOrchestrator = useChatOrchestratorStore()
const chatOrchestrator = useChatStore()
const chatSession = useChatSessionStore()
const { ingest, onAfterMessageComposed } = chatOrchestrator
const { messages } = storeToRefs(chatSession)
@@ -69,7 +72,7 @@ async function handleSend() {
messageInput.value = ''
try {
const providerConfig = providersStore.getProviderConfig(activeProvider.value)
const providerConfig = providerStore.getProviderConfig(activeProvider.value)
await ingest(textToSend, {
chatProvider: await providersStore.getProviderInstance(activeProvider.value) as ChatProvider,
@@ -49,8 +49,8 @@ vi.mock('@proj-airi/stage-ui/stores/modules/hearing', () => ({
useHearingSpeechInputPipeline: vi.fn().mockImplementation(() => mockHearingPipeline),
}))
vi.mock('@proj-airi/stage-ui/stores/providers', () => ({
useProvidersStore: vi.fn().mockImplementation(() => mockProvidersStore),
vi.mock('@proj-airi/stage-ui/stores/providers/provider', () => ({
useProviderStore: vi.fn().mockImplementation(() => mockProvidersStore),
}))
vi.mock('@proj-airi/stage-ui/stores/settings', () => ({
@@ -1,7 +1,7 @@
import type { MaybeRefOrGetter, Ref } from 'vue'
import { useHearingSpeechInputPipeline, useHearingStore } from '@proj-airi/stage-ui/stores/modules/hearing'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { useProviderStore } from '@proj-airi/stage-ui/stores/providers/provider'
import { useSettingsAudioDevice } from '@proj-airi/stage-ui/stores/settings'
import { until } from '@vueuse/core'
import { storeToRefs } from 'pinia'
@@ -23,7 +23,7 @@ export function useTranscriptions(options: TranscriptionOptions) {
const { supportsStreamInput } = storeToRefs(hearingPipeline)
const { configured: hearingConfigured, autoSendEnabled, autoSendDelay } = storeToRefs(hearingStore)
const { enabled: hearingEnabled, stream } = storeToRefs(audioDeviceSettingsStore)
const providersStore = useProvidersStore()
const providersStore = useProviderStore()
const { askPermission, startStream } = audioDeviceSettingsStore
const isListening = ref(false)
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { isStageTamagotchi } from '@proj-airi/stage-shared'
import { PageHeader } from '@proj-airi/stage-ui/components'
import { useProvidersStore } from '@proj-airi/stage-ui/stores/providers'
import { useProviderStore } from '@proj-airi/stage-ui/stores/providers/provider'
import { useTheme } from '@proj-airi/ui'
import { computed, onMounted, watch } from 'vue'
import { useI18n } from 'vue-i18n'
@@ -14,7 +14,7 @@ import { themeColorFromValue, useThemeColor } from '../composables/theme-color'
const route = useRoute()
const { isDark: dark } = useTheme()
const { t } = useI18n()
const providersStore = useProvidersStore()
const providersStore = useProviderStore()
const routeMeta = computed(() => route.meta as {
titleKey?: string
subtitleKey?: string
@@ -33,13 +33,7 @@ const providerTitle = computed(() => {
if (!providerId)
return undefined
try {
const metadata = providersStore.getProviderMetadata(providerId)
return t(metadata.nameKey)
}
catch {
return undefined
}
return providersStore.findProviderDefinition(providerId)?.nameLocalize({ t })
})
// const activeSettingsTutorial = ref('default')