Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

index.tsx 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. import { useState } from 'react'
  2. import useSWR from 'swr'
  3. import { useTranslation } from 'react-i18next'
  4. import { useContext } from 'use-context-selector'
  5. import type {
  6. FormValue,
  7. ProviderConfigModal,
  8. ProviderEnum,
  9. } from './declarations'
  10. import ModelCard from './model-card'
  11. import ModelItem from './model-item'
  12. import ModelModal from './model-modal'
  13. import SystemModel from './system-model'
  14. import config from './configs'
  15. import { ConfigurableProviders } from './utils'
  16. import {
  17. changeModelProviderPriority,
  18. deleteModelProvider,
  19. deleteModelProviderModel,
  20. fetchModelProviders,
  21. setModelProvider,
  22. } from '@/service/common'
  23. import { useToastContext } from '@/app/components/base/toast'
  24. import Confirm from '@/app/components/base/confirm/common'
  25. import { ModelType } from '@/app/components/header/account-setting/model-page/declarations'
  26. import { useEventEmitterContextContext } from '@/context/event-emitter'
  27. import { useProviderContext } from '@/context/provider-context'
  28. import I18n from '@/context/i18n'
  29. const MODEL_CARD_LIST = [
  30. config.openai,
  31. config.anthropic,
  32. ]
  33. type DeleteModel = {
  34. model_name: string
  35. model_type: string
  36. }
  37. const ModelPage = () => {
  38. const { t } = useTranslation()
  39. const { locale } = useContext(I18n)
  40. const {
  41. updateModelList,
  42. } = useProviderContext()
  43. const { data: providers, mutate: mutateProviders } = useSWR('/workspaces/current/model-providers', fetchModelProviders)
  44. const [showModal, setShowModal] = useState(false)
  45. const { notify } = useToastContext()
  46. const { eventEmitter } = useEventEmitterContextContext()
  47. const [modelModalConfig, setModelModalConfig] = useState<ProviderConfigModal | undefined>(undefined)
  48. const [confirmShow, setConfirmShow] = useState(false)
  49. const [deleteModel, setDeleteModel] = useState<DeleteModel & { providerKey: ProviderEnum }>()
  50. const [modalMode, setModalMode] = useState('add')
  51. let modelList = []
  52. if (locale === 'en') {
  53. modelList = [
  54. config.azure_openai,
  55. config.replicate,
  56. config.huggingface_hub,
  57. config.cohere,
  58. config.zhipuai,
  59. config.baichuan,
  60. config.spark,
  61. config.minimax,
  62. config.tongyi,
  63. config.wenxin,
  64. config.chatglm,
  65. config.xinference,
  66. config.openllm,
  67. config.localai,
  68. ]
  69. }
  70. else {
  71. modelList = [
  72. config.huggingface_hub,
  73. config.cohere,
  74. config.zhipuai,
  75. config.spark,
  76. config.baichuan,
  77. config.minimax,
  78. config.azure_openai,
  79. config.replicate,
  80. config.tongyi,
  81. config.wenxin,
  82. config.chatglm,
  83. config.xinference,
  84. config.openllm,
  85. config.localai,
  86. ]
  87. }
  88. const handleOpenModal = (newModelModalConfig: ProviderConfigModal | undefined, editValue?: FormValue) => {
  89. if (newModelModalConfig) {
  90. setShowModal(true)
  91. const defaultValue = editValue ? { ...newModelModalConfig.defaultValue, ...editValue } : newModelModalConfig.defaultValue
  92. setModelModalConfig({
  93. ...newModelModalConfig,
  94. defaultValue,
  95. })
  96. if (editValue)
  97. setModalMode('edit')
  98. else
  99. setModalMode('add')
  100. }
  101. }
  102. const handleCancelModal = () => {
  103. setShowModal(false)
  104. }
  105. const handleUpdateProvidersAndModelList = () => {
  106. updateModelList(ModelType.textGeneration)
  107. updateModelList(ModelType.embeddings)
  108. updateModelList(ModelType.speech2text)
  109. updateModelList(ModelType.reranking)
  110. mutateProviders()
  111. }
  112. const handleSave = async (originValue?: FormValue) => {
  113. if (originValue && modelModalConfig) {
  114. const v = modelModalConfig.filterValue ? modelModalConfig.filterValue(originValue) : originValue
  115. let body, url
  116. if (ConfigurableProviders.includes(modelModalConfig.key)) {
  117. const { model_name, model_type, ...config } = v
  118. body = {
  119. model_name,
  120. model_type,
  121. config,
  122. }
  123. url = `/workspaces/current/model-providers/${modelModalConfig.key}/models`
  124. }
  125. else {
  126. body = {
  127. config: v,
  128. }
  129. url = `/workspaces/current/model-providers/${modelModalConfig.key}`
  130. }
  131. try {
  132. eventEmitter?.emit('provider-save')
  133. const res = await setModelProvider({ url, body })
  134. if (res.result === 'success') {
  135. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  136. handleUpdateProvidersAndModelList()
  137. handleCancelModal()
  138. }
  139. eventEmitter?.emit('')
  140. }
  141. catch (e) {
  142. eventEmitter?.emit('')
  143. }
  144. }
  145. }
  146. const handleConfirm = (deleteModel: DeleteModel, providerKey: ProviderEnum) => {
  147. setDeleteModel({ ...deleteModel, providerKey })
  148. setConfirmShow(true)
  149. }
  150. const handleOperate = async ({ type, value }: Record<string, any>, provierKey: ProviderEnum) => {
  151. if (type === 'delete') {
  152. if (!value) {
  153. const res = await deleteModelProvider({ url: `/workspaces/current/model-providers/${provierKey}` })
  154. if (res.result === 'success') {
  155. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  156. handleUpdateProvidersAndModelList()
  157. }
  158. }
  159. else {
  160. handleConfirm(value, provierKey)
  161. }
  162. }
  163. if (type === 'priority') {
  164. const res = await changeModelProviderPriority({
  165. url: `/workspaces/current/model-providers/${provierKey}/preferred-provider-type`,
  166. body: {
  167. preferred_provider_type: value,
  168. },
  169. })
  170. if (res.result === 'success') {
  171. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  172. mutateProviders()
  173. }
  174. }
  175. }
  176. const handleDeleteModel = async () => {
  177. const { model_name, model_type, providerKey } = deleteModel || {}
  178. const res = await deleteModelProviderModel({
  179. url: `/workspaces/current/model-providers/${providerKey}/models?model_name=${model_name}&model_type=${model_type}`,
  180. })
  181. if (res.result === 'success') {
  182. notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
  183. setConfirmShow(false)
  184. handleUpdateProvidersAndModelList()
  185. }
  186. }
  187. return (
  188. <div className='relative pt-1 -mt-2'>
  189. <div className='flex items-center justify-between mb-2 h-8'>
  190. <div className='text-sm font-medium text-gray-800'>{t('common.modelProvider.models')}</div>
  191. <SystemModel />
  192. </div>
  193. <div className='grid grid-cols-2 gap-4 mb-6'>
  194. {
  195. MODEL_CARD_LIST.map((model, index) => (
  196. <ModelCard
  197. key={index}
  198. modelItem={model.item}
  199. currentProvider={providers?.[model.item.key]}
  200. onOpenModal={editValue => handleOpenModal(model.modal, editValue)}
  201. onOperate={v => handleOperate(v, model.item.key)}
  202. />
  203. ))
  204. }
  205. </div>
  206. {
  207. modelList.map((model, index) => (
  208. <ModelItem
  209. key={index}
  210. modelItem={model.item}
  211. currentProvider={providers?.[model.item.key]}
  212. onOpenModal={editValue => handleOpenModal(model.modal, editValue)}
  213. onOperate={v => handleOperate(v, model.item.key)}
  214. onUpdate={mutateProviders}
  215. />
  216. ))
  217. }
  218. <ModelModal
  219. isShow={showModal}
  220. modelModal={modelModalConfig}
  221. onCancel={handleCancelModal}
  222. onSave={handleSave}
  223. mode={modalMode}
  224. />
  225. <Confirm
  226. isShow={confirmShow}
  227. onCancel={() => setConfirmShow(false)}
  228. title={deleteModel?.model_name || ''}
  229. desc={t('common.modelProvider.item.deleteDesc', { modelName: deleteModel?.model_name }) || ''}
  230. onConfirm={handleDeleteModel}
  231. confirmWrapperClassName='!z-30'
  232. />
  233. </div>
  234. )
  235. }
  236. export default ModelPage