import { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import Link from 'next/link' import { useDebounce } from 'ahooks' import { RiAlertFill, RiArrowDownSLine, RiArrowRightUpLine, RiBrainLine, } from '@remixicon/react' import SystemModelSelector from './system-model-selector' import ProviderAddedCard from './provider-added-card' import type { ConfigurationMethodEnum, CustomConfigurationModelFixedFields, ModelProvider, } from './declarations' import { CustomConfigurationStatusEnum, ModelTypeEnum, } from './declarations' import { useDefaultModel, useMarketplaceAllPlugins, useModelModalHandler, } from './hooks' import Divider from '@/app/components/base/divider' import Loading from '@/app/components/base/loading' import ProviderCard from '@/app/components/plugins/provider-card' import List from '@/app/components/plugins/marketplace/list' import { useProviderContext } from '@/context/provider-context' import type { Plugin } from '@/app/components/plugins/types' import { MARKETPLACE_URL_PREFIX } from '@/config' import cn from '@/utils/classnames' import { getLocaleOnClient } from '@/i18n' type Props = { searchText: string } const ModelProviderPage = ({ searchText }: Props) => { const debouncedSearchText = useDebounce(searchText, { wait: 500 }) const { t } = useTranslation() 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 defaultModelNotConfigured = !textGenerationDefaultModel && !embeddingsDefaultModel && !speech2textDefaultModel && !rerankDefaultModel && !ttsDefaultModel const [configuredProviders, notConfiguredProviders] = useMemo(() => { const configuredProviders: ModelProvider[] = [] const notConfiguredProviders: ModelProvider[] = [] providers.forEach((provider) => { if ( provider.custom_configuration.status === CustomConfigurationStatusEnum.active || ( provider.system_configuration.enabled === true && provider.system_configuration.quota_configurations.find(item => item.quota_type === provider.system_configuration.current_quota_type) ) ) configuredProviders.push(provider) else notConfiguredProviders.push(provider) }) 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 = useModelModalHandler() const [collapse, setCollapse] = useState(false) const locale = getLocaleOnClient() const { plugins: allPlugins, isLoading: isAllPluginsLoading, } = useMarketplaceAllPlugins(providers, searchText) const cardRender = useCallback((plugin: Plugin) => { if (plugin.type === 'bundle') return null return }, []) return (
{t('common.modelProvider.models')}
{defaultModelNotConfigured &&
} {defaultModelNotConfigured && (
{t('common.modelProvider.notConfigured')}
)}
{!filteredConfiguredProviders?.length && (
{t('common.modelProvider.emptyProviderTitle')}
{t('common.modelProvider.emptyProviderTip')}
)} {!!filteredConfiguredProviders?.length && (
{filteredConfiguredProviders?.map(provider => ( handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} /> ))}
)} {!!filteredNotConfiguredProviders?.length && ( <>
{t('common.modelProvider.toBeConfigured')}
{filteredNotConfiguredProviders?.map(provider => ( handleOpenModal(provider, configurationMethod, currentCustomConfigurationModelFixedFields)} /> ))}
)}
setCollapse(!collapse)}> {t('common.modelProvider.installProvider')}
{t('common.modelProvider.discoverMore')} {t('plugin.marketplace.difyMarketplace')}
{!collapse && isAllPluginsLoading && } { !isAllPluginsLoading && !collapse && ( ) }
) } export default ModelProviderPage