123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- import type { FC } from 'react'
- import { useState } from 'react'
- import { useTranslation } from 'react-i18next'
- import {
- RiLoader2Line,
- } from '@remixicon/react'
- import type {
- CustomConfigurationModelFixedFields,
- ModelItem,
- ModelProvider,
- } from '../declarations'
- import { ConfigurationMethodEnum } from '../declarations'
- import {
- DEFAULT_BACKGROUND_COLOR,
- MODEL_PROVIDER_QUOTA_GET_PAID,
- modelTypeFormat,
- } from '../utils'
- import ProviderIcon from '../provider-icon'
- import ModelBadge from '../model-badge'
- import CredentialPanel from './credential-panel'
- import QuotaPanel from './quota-panel'
- import ModelList from './model-list'
- import AddModelButton from './add-model-button'
- import { ChevronDownDouble } from '@/app/components/base/icons/src/vender/line/arrows'
- import { fetchModelProviderModelList } from '@/service/common'
- import { useEventEmitterContextContext } from '@/context/event-emitter'
- import { IS_CE_EDITION } from '@/config'
- import { useAppContext } from '@/context/app-context'
- export const UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST = 'UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST'
- type ProviderAddedCardProps = {
- provider: ModelProvider
- onOpenModal: (configurationMethod: ConfigurationMethodEnum, currentCustomConfigurationModelFixedFields?: CustomConfigurationModelFixedFields) => void
- }
- const ProviderAddedCard: FC<ProviderAddedCardProps> = ({
- provider,
- onOpenModal,
- }) => {
- const { t } = useTranslation()
- const { eventEmitter } = useEventEmitterContextContext()
- const [fetched, setFetched] = useState(false)
- const [loading, setLoading] = useState(false)
- const [collapsed, setCollapsed] = useState(true)
- const [modelList, setModelList] = useState<ModelItem[]>([])
- const configurationMethods = provider.configurate_methods.filter(method => method !== ConfigurationMethodEnum.fetchFromRemote)
- const systemConfig = provider.system_configuration
- const hasModelList = fetched && !!modelList.length
- const { isCurrentWorkspaceManager } = useAppContext()
- const showQuota = systemConfig.enabled && [...MODEL_PROVIDER_QUOTA_GET_PAID].includes(provider.provider) && !IS_CE_EDITION
- const getModelList = async (providerName: string) => {
- if (loading)
- return
- try {
- setLoading(true)
- const modelsData = await fetchModelProviderModelList(`/workspaces/current/model-providers/${providerName}/models`)
- setModelList(modelsData.data)
- setCollapsed(false)
- setFetched(true)
- }
- finally {
- setLoading(false)
- }
- }
- const handleOpenModelList = () => {
- if (fetched) {
- setCollapsed(false)
- return
- }
- getModelList(provider.provider)
- }
- eventEmitter?.useSubscription((v: any) => {
- if (v?.type === UPDATE_MODEL_PROVIDER_CUSTOM_MODEL_LIST && v.payload === provider.provider)
- getModelList(v.payload)
- })
- return (
- <div
- className='mb-2 rounded-xl border-[0.5px] border-black/5 shadow-xs'
- style={{ background: provider.background || DEFAULT_BACKGROUND_COLOR }}
- >
- <div className='flex pl-3 py-2 pr-2 rounded-t-xl'>
- <div className='grow px-1 pt-1 pb-0.5'>
- <ProviderIcon
- className='mb-2'
- provider={provider}
- />
- <div className='flex gap-0.5'>
- {
- provider.supported_model_types.map(modelType => (
- <ModelBadge key={modelType}>
- {modelTypeFormat(modelType)}
- </ModelBadge>
- ))
- }
- </div>
- </div>
- {
- showQuota && (
- <QuotaPanel
- provider={provider}
- />
- )
- }
- {
- configurationMethods.includes(ConfigurationMethodEnum.predefinedModel) && isCurrentWorkspaceManager && (
- <CredentialPanel
- onSetup={() => onOpenModal(ConfigurationMethodEnum.predefinedModel)}
- provider={provider}
- />
- )
- }
- </div>
- {
- collapsed && (
- <div className='group flex items-center justify-between pl-2 py-1.5 pr-[11px] border-t border-t-black/5 bg-white/30 text-xs font-medium text-gray-500'>
- <div className='group-hover:hidden pl-1 pr-1.5 h-6 leading-6'>
- {
- hasModelList
- ? t('common.modelProvider.modelsNum', { num: modelList.length })
- : t('common.modelProvider.showModels')
- }
- </div>
- <div
- className='hidden group-hover:flex items-center pl-1 pr-1.5 h-6 rounded-lg hover:bg-white cursor-pointer'
- onClick={handleOpenModelList}
- >
- <ChevronDownDouble className='mr-0.5 w-3 h-3' />
- {
- hasModelList
- ? t('common.modelProvider.showModelsNum', { num: modelList.length })
- : t('common.modelProvider.showModels')
- }
- {
- loading && (
- <RiLoader2Line className='ml-0.5 animate-spin w-3 h-3' />
- )
- }
- </div>
- {
- configurationMethods.includes(ConfigurationMethodEnum.customizableModel) && isCurrentWorkspaceManager && (
- <AddModelButton
- onClick={() => onOpenModal(ConfigurationMethodEnum.customizableModel)}
- className='hidden group-hover:flex group-hover:text-primary-600'
- />
- )
- }
- </div>
- )
- }
- {
- !collapsed && (
- <ModelList
- provider={provider}
- models={modelList}
- onCollapse={() => setCollapsed(true)}
- onConfig={currentCustomConfigurationModelFixedFields => onOpenModal(ConfigurationMethodEnum.customizableModel, currentCustomConfigurationModelFixedFields)}
- onChange={(provider: string) => getModelList(provider)}
- />
- )
- }
- </div>
- )
- }
- export default ProviderAddedCard
|