選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

index.tsx 13KB

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