UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

153 lines (135 loc) • 5.15 kB
import isEqual from 'fast-deep-equal'; import { SWRResponse, mutate } from 'swr'; import { StateCreator } from 'zustand/vanilla'; import { useClientDataSWR } from '@/libs/swr'; import { aiModelService } from '@/services/aiModel'; import { AiInfraStore } from '@/store/aiInfra/store'; import { AiModelSortMap, AiProviderModelListItem, CreateAiModelParams, ToggleAiModelEnableParams, } from '@/types/aiModel'; const FETCH_AI_PROVIDER_MODEL_LIST_KEY = 'FETCH_AI_PROVIDER_MODELS'; export interface AiModelAction { batchToggleAiModels: (ids: string[], enabled: boolean) => Promise<void>; batchUpdateAiModels: (models: AiProviderModelListItem[]) => Promise<void>; clearModelsByProvider: (provider: string) => Promise<void>; clearRemoteModels: (provider: string) => Promise<void>; createNewAiModel: (params: CreateAiModelParams) => Promise<void>; fetchRemoteModelList: (providerId: string) => Promise<void>; internal_toggleAiModelLoading: (id: string, loading: boolean) => void; refreshAiModelList: () => Promise<void>; removeAiModel: (id: string, providerId: string) => Promise<void>; toggleModelEnabled: (params: Omit<ToggleAiModelEnableParams, 'providerId'>) => Promise<void>; updateAiModelsConfig: ( id: string, providerId: string, data: Partial<AiProviderModelListItem>, ) => Promise<void>; updateAiModelsSort: (providerId: string, items: AiModelSortMap[]) => Promise<void>; useFetchAiProviderModels: (id: string) => SWRResponse<AiProviderModelListItem[]>; } export const createAiModelSlice: StateCreator< AiInfraStore, [['zustand/devtools', never]], [], AiModelAction > = (set, get) => ({ batchToggleAiModels: async (ids, enabled) => { const { activeAiProvider } = get(); if (!activeAiProvider) return; await aiModelService.batchToggleAiModels(activeAiProvider, ids, enabled); await get().refreshAiModelList(); }, batchUpdateAiModels: async (models) => { const { activeAiProvider: id } = get(); if (!id) return; await aiModelService.batchUpdateAiModels(id, models); await get().refreshAiModelList(); }, clearModelsByProvider: async (provider) => { await aiModelService.clearModelsByProvider(provider); await get().refreshAiModelList(); }, clearRemoteModels: async (provider) => { await aiModelService.clearRemoteModels(provider); await get().refreshAiModelList(); }, createNewAiModel: async (data) => { await aiModelService.createAiModel(data); await get().refreshAiModelList(); }, fetchRemoteModelList: async (providerId) => { const { modelsService } = await import('@/services/models'); const data = await modelsService.getModels(providerId); if (data) { await get().batchUpdateAiModels( data.map((model) => ({ ...model, abilities: { files: model.files, functionCall: model.functionCall, reasoning: model.reasoning, vision: model.vision, }, enabled: model.enabled || false, source: 'remote', type: model.type || 'chat', })), ); await get().refreshAiModelList(); } }, internal_toggleAiModelLoading: (id, loading) => { set( (state) => { if (loading) return { aiModelLoadingIds: [...state.aiModelLoadingIds, id] }; return { aiModelLoadingIds: state.aiModelLoadingIds.filter((i) => i !== id) }; }, false, 'toggleAiModelLoading', ); }, refreshAiModelList: async () => { await mutate([FETCH_AI_PROVIDER_MODEL_LIST_KEY, get().activeAiProvider]); // make refresh provide runtime state async, not block get().refreshAiProviderRuntimeState(); }, removeAiModel: async (id, providerId) => { await aiModelService.deleteAiModel({ id, providerId }); await get().refreshAiModelList(); }, toggleModelEnabled: async (params) => { const { activeAiProvider } = get(); if (!activeAiProvider) return; get().internal_toggleAiModelLoading(params.id, true); await aiModelService.toggleModelEnabled({ ...params, providerId: activeAiProvider }); await get().refreshAiModelList(); get().internal_toggleAiModelLoading(params.id, false); }, updateAiModelsConfig: async (id, providerId, data) => { await aiModelService.updateAiModel(id, providerId, data); await get().refreshAiModelList(); }, updateAiModelsSort: async (id, items) => { await aiModelService.updateAiModelOrder(id, items); await get().refreshAiModelList(); }, useFetchAiProviderModels: (id) => useClientDataSWR<AiProviderModelListItem[]>( [FETCH_AI_PROVIDER_MODEL_LIST_KEY, id], ([, id]) => aiModelService.getAiProviderModelList(id as string), { onSuccess: (data) => { // no need to update list if the list have been init and data is the same if (get().isAiModelListInit && isEqual(data, get().aiProviderModelList)) return; set( { aiProviderModelList: data, isAiModelListInit: true }, false, `useFetchAiProviderModels/${id}`, ); }, }, ), });