Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

index.tsx 14KB

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