index.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import { useState } from 'react'
  2. import useSWR from 'swr'
  3. import { LockClosedIcon } from '@heroicons/react/24/solid'
  4. import { useTranslation } from 'react-i18next'
  5. import Link from 'next/link'
  6. import ProviderItem from './provider-item'
  7. import OpenaiHostedProvider from './openai-hosted-provider'
  8. import AnthropicHostedProvider from './anthropic-hosted-provider'
  9. import type { ProviderHosted } from '@/models/common'
  10. import { fetchProviders } from '@/service/common'
  11. import { IS_CE_EDITION } from '@/config'
  12. const providersMap: { [k: string]: any } = {
  13. 'openai-custom': {
  14. icon: 'openai',
  15. name: 'OpenAI',
  16. },
  17. 'azure_openai-custom': {
  18. icon: 'azure',
  19. name: 'Azure OpenAI Service',
  20. },
  21. 'anthropic-custom': {
  22. icon: 'anthropic',
  23. name: 'Anthropic',
  24. },
  25. }
  26. // const providersList = [
  27. // {
  28. // id: 'openai',
  29. // name: 'OpenAI',
  30. // providerKey: '1',
  31. // status: '',
  32. // child: <OpenaiProvider />
  33. // },
  34. // {
  35. // id: 'azure',
  36. // name: 'Azure OpenAI Service',
  37. // providerKey: '1',
  38. // status: 'error',
  39. // child: <AzureProvider />
  40. // },
  41. // {
  42. // id: 'anthropic',
  43. // name: 'Anthropic',
  44. // providerKey: '',
  45. // status: '',
  46. // child: <div>placeholder</div>
  47. // },
  48. // {
  49. // id: 'hugging-face',
  50. // name: 'Hugging Face Hub',
  51. // providerKey: '',
  52. // comingSoon: true,
  53. // status: '',
  54. // child: <div>placeholder</div>
  55. // }
  56. // ]
  57. const ProviderPage = () => {
  58. const { t } = useTranslation()
  59. const [activeProviderId, setActiveProviderId] = useState('')
  60. const { data, mutate } = useSWR({ url: '/workspaces/current/providers' }, fetchProviders)
  61. const providers = data?.filter(provider => providersMap[`${provider.provider_name}-${provider.provider_type}`])?.map((provider) => {
  62. const providerKey = `${provider.provider_name}-${provider.provider_type}`
  63. return {
  64. provider,
  65. icon: providersMap[providerKey].icon,
  66. name: providersMap[providerKey].name,
  67. }
  68. })
  69. const providerHosted = data?.filter(provider => provider.provider_name === 'openai' && provider.provider_type === 'system')?.[0]
  70. const anthropicHosted = data?.filter(provider => provider.provider_name === 'anthropic' && provider.provider_type === 'system')?.[0]
  71. const providedOpenaiProvider = data?.find(provider => provider.is_enabled && (provider.provider_name === 'openai' || provider.provider_name === 'azure_openai'))
  72. return (
  73. <div className='pb-7'>
  74. {
  75. providerHosted && !IS_CE_EDITION && (
  76. <>
  77. <div>
  78. <OpenaiHostedProvider provider={providerHosted as ProviderHosted} />
  79. </div>
  80. <div className='my-5 w-full h-0 border-[0.5px] border-gray-100' />
  81. </>
  82. )
  83. }
  84. {
  85. anthropicHosted && !IS_CE_EDITION && (
  86. <>
  87. <div>
  88. <AnthropicHostedProvider provider={anthropicHosted as ProviderHosted} />
  89. </div>
  90. <div className='my-5 w-full h-0 border-[0.5px] border-gray-100' />
  91. </>
  92. )
  93. }
  94. <div>
  95. {
  96. providers?.map(providerItem => (
  97. <ProviderItem
  98. key={`${providerItem.provider.provider_name}-${providerItem.provider.provider_type}`}
  99. icon={providerItem.icon}
  100. name={providerItem.name}
  101. provider={providerItem.provider}
  102. activeId={activeProviderId}
  103. onActive={aid => setActiveProviderId(aid)}
  104. onSave={() => mutate()}
  105. providedOpenaiProvider={providedOpenaiProvider}
  106. />
  107. ))
  108. }
  109. </div>
  110. <div className='fixed bottom-0 w-[472px] h-[42px] flex items-center bg-white text-xs text-gray-500'>
  111. <LockClosedIcon className='w-3 h-3 mr-1' />
  112. {t('common.provider.encrypted.front')}
  113. <Link
  114. className='text-primary-600 mx-1'
  115. target={'_blank'}
  116. href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
  117. >
  118. PKCS1_OAEP
  119. </Link>
  120. {t('common.provider.encrypted.back')}
  121. </div>
  122. </div>
  123. )
  124. }
  125. export default ProviderPage