Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

index.tsx 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. import { ReactComponent as MoreModelIcon } from '@/assets/svg/more-model.svg';
  2. import { LlmIcon } from '@/components/svg-icon';
  3. import { useTheme } from '@/components/theme-provider';
  4. import { LLMFactory } from '@/constants/llm';
  5. import { useSetModalState, useTranslate } from '@/hooks/common-hooks';
  6. import { LlmItem, useSelectLlmList } from '@/hooks/llm-hooks';
  7. import { CloseCircleOutlined, SettingOutlined } from '@ant-design/icons';
  8. import {
  9. Button,
  10. Card,
  11. Col,
  12. Collapse,
  13. CollapseProps,
  14. Divider,
  15. Flex,
  16. List,
  17. Row,
  18. Space,
  19. Spin,
  20. Tag,
  21. Tooltip,
  22. Typography,
  23. } from 'antd';
  24. import { useCallback, useMemo } from 'react';
  25. import SettingTitle from '../components/setting-title';
  26. import { isLocalLlmFactory } from '../utils';
  27. import TencentCloudModal from './Tencent-modal';
  28. import ApiKeyModal from './api-key-modal';
  29. import AzureOpenAIModal from './azure-openai-modal';
  30. import BedrockModal from './bedrock-modal';
  31. import FishAudioModal from './fish-audio-modal';
  32. import GoogleModal from './google-modal';
  33. import {
  34. useHandleDeleteFactory,
  35. useHandleDeleteLlm,
  36. useSubmitApiKey,
  37. useSubmitAzure,
  38. useSubmitBedrock,
  39. useSubmitFishAudio,
  40. useSubmitGoogle,
  41. useSubmitHunyuan,
  42. useSubmitOllama,
  43. useSubmitSpark,
  44. useSubmitSystemModelSetting,
  45. useSubmitTencentCloud,
  46. useSubmitVolcEngine,
  47. useSubmityiyan,
  48. } from './hooks';
  49. import HunyuanModal from './hunyuan-modal';
  50. import styles from './index.less';
  51. import OllamaModal from './ollama-modal';
  52. import SparkModal from './spark-modal';
  53. import SystemModelSettingModal from './system-model-setting-modal';
  54. import VolcEngineModal from './volcengine-modal';
  55. import YiyanModal from './yiyan-modal';
  56. const { Text } = Typography;
  57. interface IModelCardProps {
  58. item: LlmItem;
  59. clickApiKey: (llmFactory: string) => void;
  60. }
  61. const ModelCard = ({ item, clickApiKey }: IModelCardProps) => {
  62. const { visible, switchVisible } = useSetModalState();
  63. const { t } = useTranslate('setting');
  64. const { theme } = useTheme();
  65. const { handleDeleteLlm } = useHandleDeleteLlm(item.name);
  66. const { handleDeleteFactory } = useHandleDeleteFactory(item.name);
  67. const handleApiKeyClick = () => {
  68. clickApiKey(item.name);
  69. };
  70. const handleShowMoreClick = () => {
  71. switchVisible();
  72. };
  73. return (
  74. <List.Item>
  75. <Card
  76. className={theme === 'dark' ? styles.addedCardDark : styles.addedCard}
  77. >
  78. <Row align={'middle'}>
  79. <Col span={12}>
  80. <Flex gap={'middle'} align="center">
  81. <LlmIcon name={item.name} />
  82. <Flex vertical gap={'small'}>
  83. <b>{item.name}</b>
  84. <Text>{item.tags}</Text>
  85. </Flex>
  86. </Flex>
  87. </Col>
  88. <Col span={12} className={styles.factoryOperationWrapper}>
  89. <Space size={'middle'}>
  90. <Button onClick={handleApiKeyClick}>
  91. <Flex align="center" gap={4}>
  92. {isLocalLlmFactory(item.name) ||
  93. item.name === LLMFactory.VolcEngine ||
  94. item.name === LLMFactory.TencentHunYuan ||
  95. item.name === LLMFactory.XunFeiSpark ||
  96. item.name === LLMFactory.BaiduYiYan ||
  97. item.name === LLMFactory.FishAudio ||
  98. item.name === LLMFactory.TencentCloud ||
  99. item.name === LLMFactory.GoogleCloud ||
  100. item.name === LLMFactory.AzureOpenAI
  101. ? t('addTheModel')
  102. : 'API-Key'}
  103. <SettingOutlined />
  104. </Flex>
  105. </Button>
  106. <Button onClick={handleShowMoreClick}>
  107. <Flex align="center" gap={4}>
  108. {t('showMoreModels')}
  109. <MoreModelIcon />
  110. </Flex>
  111. </Button>
  112. <Button type={'text'} onClick={handleDeleteFactory}>
  113. <Flex align="center">
  114. <CloseCircleOutlined style={{ color: '#D92D20' }} />
  115. </Flex>
  116. </Button>
  117. </Space>
  118. </Col>
  119. </Row>
  120. {visible && (
  121. <List
  122. size="small"
  123. dataSource={item.llm}
  124. className={styles.llmList}
  125. renderItem={(item) => (
  126. <List.Item>
  127. <Space>
  128. {item.name} <Tag color="#b8b8b8">{item.type}</Tag>
  129. <Tooltip title={t('delete', { keyPrefix: 'common' })}>
  130. <Button type={'text'} onClick={handleDeleteLlm(item.name)}>
  131. <CloseCircleOutlined style={{ color: '#D92D20' }} />
  132. </Button>
  133. </Tooltip>
  134. </Space>
  135. </List.Item>
  136. )}
  137. />
  138. )}
  139. </Card>
  140. </List.Item>
  141. );
  142. };
  143. const UserSettingModel = () => {
  144. const { factoryList, myLlmList: llmList, loading } = useSelectLlmList();
  145. const { theme } = useTheme();
  146. const {
  147. saveApiKeyLoading,
  148. initialApiKey,
  149. llmFactory,
  150. onApiKeySavingOk,
  151. apiKeyVisible,
  152. hideApiKeyModal,
  153. showApiKeyModal,
  154. } = useSubmitApiKey();
  155. const {
  156. saveSystemModelSettingLoading,
  157. onSystemSettingSavingOk,
  158. systemSettingVisible,
  159. hideSystemSettingModal,
  160. showSystemSettingModal,
  161. } = useSubmitSystemModelSetting();
  162. const { t } = useTranslate('setting');
  163. const {
  164. llmAddingVisible,
  165. hideLlmAddingModal,
  166. showLlmAddingModal,
  167. onLlmAddingOk,
  168. llmAddingLoading,
  169. selectedLlmFactory,
  170. } = useSubmitOllama();
  171. const {
  172. volcAddingVisible,
  173. hideVolcAddingModal,
  174. showVolcAddingModal,
  175. onVolcAddingOk,
  176. volcAddingLoading,
  177. } = useSubmitVolcEngine();
  178. const {
  179. HunyuanAddingVisible,
  180. hideHunyuanAddingModal,
  181. showHunyuanAddingModal,
  182. onHunyuanAddingOk,
  183. HunyuanAddingLoading,
  184. } = useSubmitHunyuan();
  185. const {
  186. GoogleAddingVisible,
  187. hideGoogleAddingModal,
  188. showGoogleAddingModal,
  189. onGoogleAddingOk,
  190. GoogleAddingLoading,
  191. } = useSubmitGoogle();
  192. const {
  193. TencentCloudAddingVisible,
  194. hideTencentCloudAddingModal,
  195. showTencentCloudAddingModal,
  196. onTencentCloudAddingOk,
  197. TencentCloudAddingLoading,
  198. } = useSubmitTencentCloud();
  199. const {
  200. SparkAddingVisible,
  201. hideSparkAddingModal,
  202. showSparkAddingModal,
  203. onSparkAddingOk,
  204. SparkAddingLoading,
  205. } = useSubmitSpark();
  206. const {
  207. yiyanAddingVisible,
  208. hideyiyanAddingModal,
  209. showyiyanAddingModal,
  210. onyiyanAddingOk,
  211. yiyanAddingLoading,
  212. } = useSubmityiyan();
  213. const {
  214. FishAudioAddingVisible,
  215. hideFishAudioAddingModal,
  216. showFishAudioAddingModal,
  217. onFishAudioAddingOk,
  218. FishAudioAddingLoading,
  219. } = useSubmitFishAudio();
  220. const {
  221. bedrockAddingLoading,
  222. onBedrockAddingOk,
  223. bedrockAddingVisible,
  224. hideBedrockAddingModal,
  225. showBedrockAddingModal,
  226. } = useSubmitBedrock();
  227. const {
  228. AzureAddingVisible,
  229. hideAzureAddingModal,
  230. showAzureAddingModal,
  231. onAzureAddingOk,
  232. AzureAddingLoading,
  233. } = useSubmitAzure();
  234. const ModalMap = useMemo(
  235. () => ({
  236. [LLMFactory.Bedrock]: showBedrockAddingModal,
  237. [LLMFactory.VolcEngine]: showVolcAddingModal,
  238. [LLMFactory.TencentHunYuan]: showHunyuanAddingModal,
  239. [LLMFactory.XunFeiSpark]: showSparkAddingModal,
  240. [LLMFactory.BaiduYiYan]: showyiyanAddingModal,
  241. [LLMFactory.FishAudio]: showFishAudioAddingModal,
  242. [LLMFactory.TencentCloud]: showTencentCloudAddingModal,
  243. [LLMFactory.GoogleCloud]: showGoogleAddingModal,
  244. [LLMFactory.AzureOpenAI]: showAzureAddingModal,
  245. }),
  246. [
  247. showBedrockAddingModal,
  248. showVolcAddingModal,
  249. showHunyuanAddingModal,
  250. showTencentCloudAddingModal,
  251. showSparkAddingModal,
  252. showyiyanAddingModal,
  253. showFishAudioAddingModal,
  254. showGoogleAddingModal,
  255. showAzureAddingModal,
  256. ],
  257. );
  258. const handleAddModel = useCallback(
  259. (llmFactory: string) => {
  260. if (isLocalLlmFactory(llmFactory)) {
  261. showLlmAddingModal(llmFactory);
  262. } else if (llmFactory in ModalMap) {
  263. ModalMap[llmFactory as keyof typeof ModalMap]();
  264. } else {
  265. showApiKeyModal({ llm_factory: llmFactory });
  266. }
  267. },
  268. [showApiKeyModal, showLlmAddingModal, ModalMap],
  269. );
  270. const items: CollapseProps['items'] = [
  271. {
  272. key: '1',
  273. label: t('addedModels'),
  274. children: (
  275. <List
  276. grid={{ gutter: 16, column: 1 }}
  277. dataSource={llmList}
  278. renderItem={(item) => (
  279. <ModelCard item={item} clickApiKey={handleAddModel}></ModelCard>
  280. )}
  281. />
  282. ),
  283. },
  284. {
  285. key: '2',
  286. label: t('modelsToBeAdded'),
  287. children: (
  288. <List
  289. grid={{
  290. gutter: {
  291. xs: 8,
  292. sm: 10,
  293. md: 12,
  294. lg: 16,
  295. xl: 20,
  296. xxl: 24,
  297. },
  298. xs: 1,
  299. sm: 1,
  300. md: 2,
  301. lg: 3,
  302. xl: 4,
  303. xxl: 8,
  304. }}
  305. dataSource={factoryList}
  306. renderItem={(item) => (
  307. <List.Item>
  308. <Card
  309. className={
  310. theme === 'dark'
  311. ? styles.toBeAddedCardDark
  312. : styles.toBeAddedCard
  313. }
  314. >
  315. <Flex vertical gap={'middle'}>
  316. <LlmIcon name={item.name} imgClass="h-12 w-auto" />
  317. <Flex vertical gap={'middle'}>
  318. <b>
  319. <Text ellipsis={{ tooltip: item.name }}>{item.name}</Text>
  320. </b>
  321. <Text className={styles.modelTags}>{item.tags}</Text>
  322. </Flex>
  323. </Flex>
  324. <Divider className={styles.modelDivider}></Divider>
  325. <Button
  326. type="link"
  327. onClick={() => handleAddModel(item.name)}
  328. className={styles.addButton}
  329. >
  330. {t('addTheModel')}
  331. </Button>
  332. </Card>
  333. </List.Item>
  334. )}
  335. />
  336. ),
  337. },
  338. ];
  339. return (
  340. <section id="xx" className={styles.modelWrapper}>
  341. <Spin spinning={loading}>
  342. <section className={styles.modelContainer}>
  343. <SettingTitle
  344. title={t('model')}
  345. description={t('modelDescription')}
  346. showRightButton
  347. clickButton={showSystemSettingModal}
  348. ></SettingTitle>
  349. <Divider></Divider>
  350. <Collapse defaultActiveKey={['1', '2']} ghost items={items} />
  351. </section>
  352. </Spin>
  353. <ApiKeyModal
  354. visible={apiKeyVisible}
  355. hideModal={hideApiKeyModal}
  356. loading={saveApiKeyLoading}
  357. initialValue={initialApiKey}
  358. onOk={onApiKeySavingOk}
  359. llmFactory={llmFactory}
  360. ></ApiKeyModal>
  361. {systemSettingVisible && (
  362. <SystemModelSettingModal
  363. visible={systemSettingVisible}
  364. onOk={onSystemSettingSavingOk}
  365. hideModal={hideSystemSettingModal}
  366. loading={saveSystemModelSettingLoading}
  367. ></SystemModelSettingModal>
  368. )}
  369. <OllamaModal
  370. visible={llmAddingVisible}
  371. hideModal={hideLlmAddingModal}
  372. onOk={onLlmAddingOk}
  373. loading={llmAddingLoading}
  374. llmFactory={selectedLlmFactory}
  375. ></OllamaModal>
  376. <VolcEngineModal
  377. visible={volcAddingVisible}
  378. hideModal={hideVolcAddingModal}
  379. onOk={onVolcAddingOk}
  380. loading={volcAddingLoading}
  381. llmFactory={LLMFactory.VolcEngine}
  382. ></VolcEngineModal>
  383. <HunyuanModal
  384. visible={HunyuanAddingVisible}
  385. hideModal={hideHunyuanAddingModal}
  386. onOk={onHunyuanAddingOk}
  387. loading={HunyuanAddingLoading}
  388. llmFactory={LLMFactory.TencentHunYuan}
  389. ></HunyuanModal>
  390. <GoogleModal
  391. visible={GoogleAddingVisible}
  392. hideModal={hideGoogleAddingModal}
  393. onOk={onGoogleAddingOk}
  394. loading={GoogleAddingLoading}
  395. llmFactory={LLMFactory.GoogleCloud}
  396. ></GoogleModal>
  397. <TencentCloudModal
  398. visible={TencentCloudAddingVisible}
  399. hideModal={hideTencentCloudAddingModal}
  400. onOk={onTencentCloudAddingOk}
  401. loading={TencentCloudAddingLoading}
  402. llmFactory={LLMFactory.TencentCloud}
  403. ></TencentCloudModal>
  404. <SparkModal
  405. visible={SparkAddingVisible}
  406. hideModal={hideSparkAddingModal}
  407. onOk={onSparkAddingOk}
  408. loading={SparkAddingLoading}
  409. llmFactory={LLMFactory.XunFeiSpark}
  410. ></SparkModal>
  411. <YiyanModal
  412. visible={yiyanAddingVisible}
  413. hideModal={hideyiyanAddingModal}
  414. onOk={onyiyanAddingOk}
  415. loading={yiyanAddingLoading}
  416. llmFactory={LLMFactory.BaiduYiYan}
  417. ></YiyanModal>
  418. <FishAudioModal
  419. visible={FishAudioAddingVisible}
  420. hideModal={hideFishAudioAddingModal}
  421. onOk={onFishAudioAddingOk}
  422. loading={FishAudioAddingLoading}
  423. llmFactory={LLMFactory.FishAudio}
  424. ></FishAudioModal>
  425. <BedrockModal
  426. visible={bedrockAddingVisible}
  427. hideModal={hideBedrockAddingModal}
  428. onOk={onBedrockAddingOk}
  429. loading={bedrockAddingLoading}
  430. llmFactory={LLMFactory.Bedrock}
  431. ></BedrockModal>
  432. <AzureOpenAIModal
  433. visible={AzureAddingVisible}
  434. hideModal={hideAzureAddingModal}
  435. onOk={onAzureAddingOk}
  436. loading={AzureAddingLoading}
  437. llmFactory={LLMFactory.AzureOpenAI}
  438. ></AzureOpenAIModal>
  439. </section>
  440. );
  441. };
  442. export default UserSettingModel;