From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001 From: wwf <yearningwang@iqtogether.com> Date: 星期三, 04 六月 2025 15:17:49 +0800 Subject: [PATCH] 初始化 --- app/components/header/account-setting/model-provider-page/index.tsx | 201 ++++++++++++++++++++++++-------------------------- 1 files changed, 96 insertions(+), 105 deletions(-) diff --git a/app/components/header/account-setting/model-provider-page/index.tsx b/app/components/header/account-setting/model-provider-page/index.tsx index 7c4e2ea..a8a5a0c 100644 --- a/app/components/header/account-setting/model-provider-page/index.tsx +++ b/app/components/header/account-setting/model-provider-page/index.tsx @@ -1,46 +1,39 @@ import { useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { useDebounce } from 'ahooks' -import { - RiAlertFill, - RiBrainLine, -} from '@remixicon/react' import SystemModelSelector from './system-model-selector' -import ProviderAddedCard from './provider-added-card' +import ProviderAddedCard, { UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST } from './provider-added-card' +import ProviderCard from './provider-card' import type { - ConfigurationMethodEnum, CustomConfigurationModelFixedFields, ModelProvider, } from './declarations' import { + ConfigurationMethodEnum, CustomConfigurationStatusEnum, ModelTypeEnum, } from './declarations' import { useDefaultModel, - useModelModalHandler, + useUpdateModelList, + useUpdateModelProviders, } from './hooks' -import InstallFromMarketplace from './install-from-marketplace' +import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' import { useProviderContext } from '@/context/provider-context' -import cn from '@/utils/classnames' -import { useSelector as useAppContextSelector } from '@/context/app-context' +import { useModalContextSelector } from '@/context/modal-context' +import { useEventEmitterContextContext } from '@/context/event-emitter' -type Props = { - searchText: string -} - -const FixedModelProvider = ['langgenius/openai/openai', 'langgenius/anthropic/anthropic'] - -const ModelProviderPage = ({ searchText }: Props) => { - const debouncedSearchText = useDebounce(searchText, { wait: 500 }) +const ModelProviderPage = () => { const { t } = useTranslation() + const { eventEmitter } = useEventEmitterContextContext() + const updateModelProviders = useUpdateModelProviders() + const updateModelList = useUpdateModelList() const { data: textGenerationDefaultModel } = useDefaultModel(ModelTypeEnum.textGeneration) const { data: embeddingsDefaultModel } = useDefaultModel(ModelTypeEnum.textEmbedding) const { data: rerankDefaultModel } = useDefaultModel(ModelTypeEnum.rerank) const { data: speech2textDefaultModel } = useDefaultModel(ModelTypeEnum.speech2text) const { data: ttsDefaultModel } = useDefaultModel(ModelTypeEnum.tts) const { modelProviders: providers } = useProviderContext() - const { enable_marketplace } = useAppContextSelector(s => s.systemFeatures) + const setShowModelModal = useModalContextSelector(state => state.setShowModelModal) const defaultModelNotConfigured = !textGenerationDefaultModel && !embeddingsDefaultModel && !speech2textDefaultModel && !rerankDefaultModel && !ttsDefaultModel const [configuredProviders, notConfiguredProviders] = useMemo(() => { const configuredProviders: ModelProvider[] = [] @@ -59,99 +52,97 @@ notConfiguredProviders.push(provider) }) - configuredProviders.sort((a, b) => { - if (FixedModelProvider.includes(a.provider) && FixedModelProvider.includes(b.provider)) - return FixedModelProvider.indexOf(a.provider) - FixedModelProvider.indexOf(b.provider) > 0 ? 1 : -1 - else if (FixedModelProvider.includes(a.provider)) - return -1 - else if (FixedModelProvider.includes(b.provider)) - return 1 - return 0 - }) - return [configuredProviders, notConfiguredProviders] }, [providers]) - const [filteredConfiguredProviders, filteredNotConfiguredProviders] = useMemo(() => { - const filteredConfiguredProviders = configuredProviders.filter( - provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase()) - || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())), - ) - const filteredNotConfiguredProviders = notConfiguredProviders.filter( - provider => provider.provider.toLowerCase().includes(debouncedSearchText.toLowerCase()) - || Object.values(provider.label).some(text => text.toLowerCase().includes(debouncedSearchText.toLowerCase())), - ) - return [filteredConfiguredProviders, filteredNotConfiguredProviders] - }, [configuredProviders, debouncedSearchText, notConfiguredProviders]) + const handleOpenModal = ( + provider: ModelProvider, + configurateMethod: ConfigurationMethodEnum, + CustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields, + ) => { + setShowModelModal({ + payload: { + currentProvider: provider, + currentConfigurationMethod: configurateMethod, + currentCustomConfigurationModelFixedFields: CustomConfigurationModelFixedFields, + }, + onSaveCallback: () => { + updateModelProviders() - const handleOpenModal = useModelModalHandler() + if (configurateMethod === ConfigurationMethodEnum.predefinedModel) { + provider.supported_model_types.forEach((type) => { + updateModelList(type) + }) + } + + if (configurateMethod === ConfigurationMethodEnum.customizableModel && provider.custom_configuration.status === CustomConfigurationStatusEnum.active) { + eventEmitter?.emit({ + type: UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST, + payload: provider.provider, + } as any) + + if (CustomConfigurationModelFixedFields?.__model_type) + updateModelList(CustomConfigurationModelFixedFields?.__model_type) + } + }, + }) + } return ( - <div className='relative -mt-2 pt-1'> - <div className={cn('mb-2 flex items-center')}> - <div className='system-md-semibold grow text-text-primary'>{t('common.modelProvider.models')}</div> - <div className={cn( - 'relative flex shrink-0 items-center justify-end gap-2 rounded-lg border border-transparent p-px', - defaultModelNotConfigured && 'border-components-panel-border bg-components-panel-bg-blur pl-2 shadow-xs', - )}> - {defaultModelNotConfigured && <div className='absolute bottom-0 left-0 right-0 top-0 opacity-40' style={{ background: 'linear-gradient(92deg, rgba(247, 144, 9, 0.25) 0%, rgba(255, 255, 255, 0.00) 100%)' }} />} - {defaultModelNotConfigured && ( - <div className='system-xs-medium flex items-center gap-1 text-text-primary'> - <RiAlertFill className='h-4 w-4 text-text-warning-secondary' /> - {t('common.modelProvider.notConfigured')} - </div> - )} - <SystemModelSelector - notConfigured={defaultModelNotConfigured} - textGenerationDefaultModel={textGenerationDefaultModel} - embeddingsDefaultModel={embeddingsDefaultModel} - rerankDefaultModel={rerankDefaultModel} - speech2textDefaultModel={speech2textDefaultModel} - ttsDefaultModel={ttsDefaultModel} - /> - </div> + <div className='relative pt-1 -mt-2'> + <div className={`flex items-center justify-between mb-2 h-8 ${defaultModelNotConfigured && 'px-3 bg-[#FFFAEB] rounded-lg border border-[#FEF0C7]'}`}> + { + defaultModelNotConfigured + ? ( + <div className='flex items-center text-xs font-medium text-gray-700'> + <AlertTriangle className='mr-1 w-3 h-3 text-[#F79009]' /> + {t('common.modelProvider.notConfigured')} + </div> + ) + : <div className='text-sm font-medium text-gray-800'>{t('common.modelProvider.models')}</div> + } + <SystemModelSelector + textGenerationDefaultModel={textGenerationDefaultModel} + embeddingsDefaultModel={embeddingsDefaultModel} + rerankDefaultModel={rerankDefaultModel} + speech2textDefaultModel={speech2textDefaultModel} + ttsDefaultModel={ttsDefaultModel} + /> </div> - {!filteredConfiguredProviders?.length && ( - <div className='mb-2 rounded-[10px] bg-workflow-process-bg p-4'> - <div className='flex h-10 w-10 items-center justify-center rounded-[10px] border-[0.5px] border-components-card-border bg-components-card-bg shadow-lg backdrop-blur'> - <RiBrainLine className='h-5 w-5 text-text-primary' /> - </div> - <div className='system-sm-medium mt-2 text-text-secondary'>{t('common.modelProvider.emptyProviderTitle')}</div> - <div className='system-xs-regular mt-1 text-text-tertiary'>{t('common.modelProvider.emptyProviderTip')}</div> - </div> - )} - {!!filteredConfiguredProviders?.length && ( - <div className='relative'> - {filteredConfiguredProviders?.map(provider => ( - <ProviderAddedCard - key={provider.provider} - provider={provider} - onOpenModal={(configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} - /> - ))} - </div> - )} - {!!filteredNotConfiguredProviders?.length && ( - <> - <div className='system-md-semibold mb-2 flex items-center pt-2 text-text-primary'>{t('common.modelProvider.toBeConfigured')}</div> - <div className='relative'> - {filteredNotConfiguredProviders?.map(provider => ( - <ProviderAddedCard - notConfigured - key={provider.provider} - provider={provider} - onOpenModal={(configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} - /> - ))} - </div> - </> - )} { - enable_marketplace && ( - <InstallFromMarketplace - providers={providers} - searchText={searchText} - /> + !!configuredProviders?.length && ( + <div className='pb-3'> + { + configuredProviders?.map(provider => ( + <ProviderAddedCard + key={provider.provider} + provider={provider} + onOpenModal={(configurateMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => handleOpenModal(provider, configurateMethod, currentCustomConfigurationModelFixedFields)} + /> + )) + } + </div> + ) + } + { + !!notConfiguredProviders?.length && ( + <> + <div className='flex items-center mb-2 text-xs font-semibold text-gray-500'> + + {t('common.modelProvider.addMoreModelProvider')} + <span className='grow ml-3 h-[1px] bg-gradient-to-r from-[#f3f4f6]' /> + </div> + <div className='grid grid-cols-3 gap-2'> + { + notConfiguredProviders?.map(provider => ( + <ProviderCard + key={provider.provider} + provider={provider} + onOpenModal={(configurateMethod: ConfigurationMethodEnum) => handleOpenModal(provider, configurateMethod)} + /> + )) + } + </div> + </> ) } </div> -- Gitblit v1.8.0