From 77a8b23d761bbec914cfe6b7009ae9597bcac0a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=96=E9=83=BD=E7=88=B1=E6=8A=A4=E5=8A=A8=E7=89=A9?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A?= <87239270+1355873789@users.noreply.github.com> Date: Tue, 5 Nov 2024 15:56:36 +0800 Subject: [PATCH 1/5] Add Providers 1. Fix the naming error of the Grok model 2. Add new providers: Grok, Mistral, Jina, Hyperbolic --- src/renderer/src/config/models.ts | 58 ++++++++++++++++++++++-- src/renderer/src/config/providers.ts | 52 +++++++++++++++++++++ src/renderer/src/i18n/locales/en-us.json | 4 ++ src/renderer/src/i18n/locales/zh-cn.json | 4 ++ src/renderer/src/i18n/locales/zh-tw.json | 4 ++ src/renderer/src/store/index.ts | 2 +- src/renderer/src/store/llm.ts | 36 +++++++++++++++ src/renderer/src/store/migrate.ts | 47 +++++++++++++++++++ 8 files changed, 203 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 0b8d8dd5..72ac370f 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -44,8 +44,6 @@ import GemmaModelLogo from '@renderer/assets/images/models/gemma.png' import GemmaModelLogoDark from '@renderer/assets/images/models/gemma_dark.png' import GoogleModelLogo from '@renderer/assets/images/models/google.png' import GoogleModelLogoDark from '@renderer/assets/images/models/google.png' -import GorkModelLogo from '@renderer/assets/images/models/gork.png' -import GorkModelLogoDark from '@renderer/assets/images/models/gork_dark.png' import ChatGPT35ModelLogo from '@renderer/assets/images/models/gpt_3.5.png' import ChatGPT4ModelLogo from '@renderer/assets/images/models/gpt_4.png' import ChatGptModelLogoDakr from '@renderer/assets/images/models/gpt_dark.png' @@ -53,6 +51,8 @@ import ChatGPT35ModelLogoDark from '@renderer/assets/images/models/gpt_dark.png' import ChatGPT4ModelLogoDark from '@renderer/assets/images/models/gpt_dark.png' import ChatGPTo1ModelLogoDark from '@renderer/assets/images/models/gpt_dark.png' import ChatGPTo1ModelLogo from '@renderer/assets/images/models/gpt_o1.png' +import GrokModelLogo from '@renderer/assets/images/models/grok.png' +import GrokModelLogoDark from '@renderer/assets/images/models/grok_dark.png' import GrypheModelLogo from '@renderer/assets/images/models/gryphe.png' import GrypheModelLogoDark from '@renderer/assets/images/models/gryphe_dark.png' import HailuoModelLogo from '@renderer/assets/images/models/hailuo.png' @@ -65,6 +65,8 @@ import IbmModelLogo from '@renderer/assets/images/models/ibm.png' import IbmModelLogoDark from '@renderer/assets/images/models/ibm_dark.png' import InternlmModelLogo from '@renderer/assets/images/models/internlm.png' import InternlmModelLogoDark from '@renderer/assets/images/models/internlm_dark.png' +import JinaModelLogo from '@renderer/assets/images/models/jina.png' +import JinaModelLogoDark from '@renderer/assets/images/models/jina_dark.png' import KeLingModelLogo from '@renderer/assets/images/models/keling.png' import KeLingModelLogoDark from '@renderer/assets/images/models/keling_dark.png' import LlamaModelLogo from '@renderer/assets/images/models/llama.png' @@ -154,6 +156,7 @@ export function getModelLogo(modelId: string) { } const logoMap = { + jina: isLight ? JinaModelLogo : JinaModelLogoDark, abab: isLight ? MinimaxModelLogo : MinimaxModelLogoDark, 'o1-': isLight ? ChatGPTo1ModelLogo : ChatGPTo1ModelLogoDark, 'gpt-3': isLight ? ChatGPT35ModelLogo : ChatGPT35ModelLogoDark, @@ -197,7 +200,7 @@ export function getModelLogo(modelId: string) { dbrx: isLight ? DbrxModelLogo : DbrxModelLogo, flashaudio: isLight ? FlashaudioModelLogo : FlashaudioModelLogoDark, flux: isLight ? FluxModelLogo : FluxModelLogoDark, - gork: isLight ? GorkModelLogo : GorkModelLogoDark, + grok: isLight ? GrokModelLogo : GrokModelLogoDark, hunyuan: isLight ? HunyuanModelLogo : HunyuanModelLogoDark, internlm: isLight ? InternlmModelLogo : InternlmModelLogoDark, llava: isLight ? LLavaModelLogo : LLavaModelLogoDark, @@ -764,6 +767,55 @@ export const SYSTEM_MODELS: Record = { group: 'abab5' } ], + hyperbolic: [ + { + id: 'Qwen/Qwen2-VL-72B-Instruct', + provider: 'hyperbolic', + name: 'Qwen2-VL-72B-Instruct', + group: 'Qwen2-VL' + }, + { + id: 'Qwen/Qwen2-VL-7B-Instruct', + provider: 'hyperbolic', + name: 'Qwen2-VL-7B-Instruct', + group: 'Qwen2-VL' + }, + { + id: 'mistralai/Pixtral-12B-2409', + provider: 'hyperbolic', + name: 'Pixtral-12B-2409', + group: 'Pixtral' + }, + { + id: 'meta-llama/Meta-Llama-3.1-405B', + provider: 'hyperbolic', + name: 'Meta-Llama-3.1-405B', + group: 'Meta-Llama-3.1' + } + ], + grok: [ + { + id: 'grok-beta', + provider: 'grok', + name: 'Grok Beta', + group: 'Grok' + } + ], + mistral: [ + { + id: 'pixtral-12b-2409', + provider: 'mistral', + name: 'Pixtral-12B-2409', + group: 'Pixtral' + }, + { + id: 'open-mistral-nemo', + provider: 'mistral', + name: 'Open-Mistral-Nemo', + group: 'Mistral' + } + ], + jina: [], aihubmix: [ { id: 'gpt-4o-mini', diff --git a/src/renderer/src/config/providers.ts b/src/renderer/src/config/providers.ts index f3b9fb8b..5e47714d 100644 --- a/src/renderer/src/config/providers.ts +++ b/src/renderer/src/config/providers.ts @@ -24,6 +24,10 @@ import StepProviderLogo from '@renderer/assets/images/providers/step.png' import TogetherProviderLogo from '@renderer/assets/images/providers/together.png' import ZeroOneProviderLogo from '@renderer/assets/images/providers/zero-one.png' import ZhipuProviderLogo from '@renderer/assets/images/providers/zhipu.png' +import GrokProviderLogo from '@renderer/assets/images/providers/grok.png' +import HyperbolicProviderLogo from '@renderer/assets/images/providers/hyperbolic.png' +import MistralProviderLogo from '@renderer/assets/images/providers/mistral.png' +import JinaProviderLogo from '@renderer/assets/images/providers/jina.png' export function getProviderLogo(providerId: string) { switch (providerId) { @@ -79,6 +83,14 @@ export function getProviderLogo(providerId: string) { return AzureProviderLogo case 'hunyuan': return HunyuanProviderLogo + case 'grok': + return GrokProviderLogo + case 'hyperbolic': + return HyperbolicProviderLogo + case 'mistral': + return MistralProviderLogo + case 'jina': + return JinaProviderLogo default: return undefined } @@ -298,6 +310,46 @@ export const PROVIDER_CONFIG = { models: 'https://docs.anthropic.com/en/docs/about-claude/models' } }, + grok: { + api: { + url: 'https://api.x.ai' + }, + websites: { + official: 'https://x.ai/', + docs: 'https://docs.x.ai/', + models: 'https://docs.x.ai/docs#getting-started' + } + }, + hyperbolic: { + api: { + url: 'https://api.hyperbolic.xyz' + }, + websites: { + official: 'https://app.hyperbolic.xyz', + docs: 'https://docs.hyperbolic.xyz', + models: 'https://app.hyperbolic.xyz/models' + } + }, + mistral: { + api: { + url: 'https://api.mistral.ai' + }, + websites: { + official: 'https://mistral.ai', + docs: 'https://docs.mistral.ai', + models: 'https://docs.mistral.ai/getting-started/models/models_overview' + } + }, + jina: { + api: { + url: 'https://api.jina.ai' + }, + websites: { + official: 'https://jina.ai', + docs: 'https://jina.ai', + models: 'https://jina.ai' + } + }, aihubmix: { api: { url: 'https://aihubmix.com' diff --git a/src/renderer/src/i18n/locales/en-us.json b/src/renderer/src/i18n/locales/en-us.json index b1762cea..da3f0658 100644 --- a/src/renderer/src/i18n/locales/en-us.json +++ b/src/renderer/src/i18n/locales/en-us.json @@ -215,6 +215,10 @@ "locate.message": "Locate the message" }, "provider": { + "jina": "Jina", + "mistral": "Mistral", + "hyperbolic": "Hyperbolic", + "grok": "Grok", "nvidia": "Nvidia", "hunyuan": "Tencent Hunyuan", "zhinao": "360AI", diff --git a/src/renderer/src/i18n/locales/zh-cn.json b/src/renderer/src/i18n/locales/zh-cn.json index c1ba3d7f..86d5305b 100644 --- a/src/renderer/src/i18n/locales/zh-cn.json +++ b/src/renderer/src/i18n/locales/zh-cn.json @@ -215,6 +215,10 @@ "locate.message": "定位到消息" }, "provider": { + "jina": "Jina", + "mistral": "Mistral", + "hyperbolic": "Hyperbolic", + "grok": "Grok", "nvidia": "英伟达", "hunyuan": "腾讯混元", "zhinao": "360智脑", diff --git a/src/renderer/src/i18n/locales/zh-tw.json b/src/renderer/src/i18n/locales/zh-tw.json index 27ff408b..c6ab1fd7 100644 --- a/src/renderer/src/i18n/locales/zh-tw.json +++ b/src/renderer/src/i18n/locales/zh-tw.json @@ -215,6 +215,10 @@ "locate.message": "定位到訊息" }, "provider": { + "jina": "Jina", + "mistral": "Mistral", + "hyperbolic": "Hyperbolic", + "grok": "Grok", "nvidia": "輝達", "zhinao": "360智腦", "hunyuan": "騰訊混元", diff --git a/src/renderer/src/store/index.ts b/src/renderer/src/store/index.ts index df2d6a56..32157109 100644 --- a/src/renderer/src/store/index.ts +++ b/src/renderer/src/store/index.ts @@ -24,7 +24,7 @@ const persistedReducer = persistReducer( { key: 'cherry-studio', storage, - version: 37, + version: 38, blacklist: ['runtime'], migrate }, diff --git a/src/renderer/src/store/llm.ts b/src/renderer/src/store/llm.ts index 39912f9d..66966001 100644 --- a/src/renderer/src/store/llm.ts +++ b/src/renderer/src/store/llm.ts @@ -249,6 +249,42 @@ const initialState: LlmState = { isSystem: true, enabled: false }, + { + id: 'grok', + name: 'Grok', + apiKey: '', + apiHost: 'https://api.x.ai', + models: SYSTEM_MODELS.grok, + isSystem: true, + enabled: false + }, + { + id: 'hyperbolic', + name: 'Hyperbolic', + apiKey: '', + apiHost: 'https://api.hyperbolic.xyz', + models: SYSTEM_MODELS.hyperbolic, + isSystem: true, + enabled: false + }, + { + id: 'mistral', + name: 'Mistral', + apiKey: '', + apiHost: 'https://api.mistral.ai', + models: SYSTEM_MODELS.mistral, + isSystem: true, + enabled: false + }, + { + id: 'jina', + name: 'Jina', + apiKey: '', + apiHost: 'https://api.jina.ai', + models: SYSTEM_MODELS.jina, + isSystem: true, + enabled: false + }, { id: 'aihubmix', name: 'AiHubMix', diff --git a/src/renderer/src/store/migrate.ts b/src/renderer/src/store/migrate.ts index 773005b2..784ad5b7 100644 --- a/src/renderer/src/store/migrate.ts +++ b/src/renderer/src/store/migrate.ts @@ -622,6 +622,53 @@ const migrateConfig = { '37': (state: RootState) => { state.settings.messageStyle = 'plain' return state + }, + '38': (state: RootState) => { + return { + ...state, + llm: { + ...state.llm, + providers: [ + ...state.llm.providers, + { + id: 'grok', + name: 'Grok', + apiKey: '', + apiHost: 'https://api.x.ai', + models: SYSTEM_MODELS.grok, + isSystem: true, + enabled: false + }, + { + id: 'hyperbolic', + name: 'Hyperbolic', + apiKey: '', + apiHost: 'https://api.hyperbolic.xyz', + models: SYSTEM_MODELS.hyperbolic, + isSystem: true, + enabled: false + }, + { + id: 'mistral', + name: 'Mistral', + apiKey: '', + apiHost: 'https://api.mistral.ai', + models: SYSTEM_MODELS.mistral, + isSystem: true, + enabled: false + }, + { + id: 'jina', + name: 'Jina', + apiKey: '', + apiHost: 'https://api.jina.ai', + models: SYSTEM_MODELS.jina, + isSystem: true, + enabled: false + } + ] + } + } } } From aa864f3876a87782dc30c4d2b181d1f158c6231d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=96=E9=83=BD=E7=88=B1=E6=8A=A4=E5=8A=A8=E7=89=A9?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A?= <87239270+1355873789@users.noreply.github.com> Date: Tue, 5 Nov 2024 16:04:30 +0800 Subject: [PATCH 2/5] Add new model and provider avatars. --- .../assets/images/models/{gork.png => grok.png} | Bin .../models/{gork_dark.png => grok_dark.png} | Bin src/renderer/src/assets/images/models/jina.png | Bin 0 -> 3306 bytes .../src/assets/images/models/jina_dark.png | Bin 0 -> 3322 bytes .../src/assets/images/providers/grok.png | Bin 0 -> 6572 bytes .../src/assets/images/providers/jina.png | Bin 0 -> 3306 bytes .../src/assets/images/providers/mistral.png | Bin 0 -> 2861 bytes 7 files changed, 0 insertions(+), 0 deletions(-) rename src/renderer/src/assets/images/models/{gork.png => grok.png} (100%) rename src/renderer/src/assets/images/models/{gork_dark.png => grok_dark.png} (100%) create mode 100644 src/renderer/src/assets/images/models/jina.png create mode 100644 src/renderer/src/assets/images/models/jina_dark.png create mode 100644 src/renderer/src/assets/images/providers/grok.png create mode 100644 src/renderer/src/assets/images/providers/jina.png create mode 100644 src/renderer/src/assets/images/providers/mistral.png diff --git a/src/renderer/src/assets/images/models/gork.png b/src/renderer/src/assets/images/models/grok.png similarity index 100% rename from src/renderer/src/assets/images/models/gork.png rename to src/renderer/src/assets/images/models/grok.png diff --git a/src/renderer/src/assets/images/models/gork_dark.png b/src/renderer/src/assets/images/models/grok_dark.png similarity index 100% rename from src/renderer/src/assets/images/models/gork_dark.png rename to src/renderer/src/assets/images/models/grok_dark.png diff --git a/src/renderer/src/assets/images/models/jina.png b/src/renderer/src/assets/images/models/jina.png new file mode 100644 index 0000000000000000000000000000000000000000..f48f43204c9ee91c4c7e7ae56b0c6a9154c544fd GIT binary patch literal 3306 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 C%nF_W literal 0 HcmV?d00001 diff --git a/src/renderer/src/assets/images/models/jina_dark.png b/src/renderer/src/assets/images/models/jina_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..db83caa88d5021a094d5417db367c8aa0e1ec985 GIT binary patch literal 3322 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 literal 0 HcmV?d00001 diff --git a/src/renderer/src/assets/images/providers/grok.png b/src/renderer/src/assets/images/providers/grok.png new file mode 100644 index 0000000000000000000000000000000000000000..fd2165705a8338851db3446dfb8e3ce0bcebbb3e GIT binary patch literal 6572 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 C%nF_W literal 0 HcmV?d00001 diff --git a/src/renderer/src/assets/images/providers/mistral.png b/src/renderer/src/assets/images/providers/mistral.png new file mode 100644 index 0000000000000000000000000000000000000000..0ed97c8194d48bea0a46745549cebf934e1f2708 GIT binary patch literal 2861 zcmchZ`#%#3AII5>5t)<7Z8MfzJYk!YODxH)+&ZP+w~J%`GsqDe&?}!v*Zbi%+<{hpIt_l zb*`%IP|^U+T0}zod6Fg>oPX{|&(XBY*-r&v4A_g4)04*vA#$QUK#t{X(wmOK5=KFLnmIT_XR0AxT z0+0+<|My|3PbxVs1bp%9>yP*4e_jkX{9Xt9P;F$u*9zzEV}WAz43;ym@`v;djpMW$lXUrG0rb#q{#;sj zvFzSm3iRNsM&G-pE3e)9S8KvZG#6bah zmXy_9`ETcsI&pVc3vM9d%a^Fhn3Z=n-4%Wv)emK7g==m)+AFpDh>w>{UIB=}t~53L ziS=V8(uA#@nJT}93+D7~6@QmR_O33jM>mX}xB8Pji!v@2@cW%~*^Nz$_kc{&i_7~) z0!=di56kND@@*}p362S-8zyVQ!5ITf;4u;^FuvJ2=XN|MZhL1uo2Q3XBi>YGs-Sbw z0UJPM@rh0+5rXLSqw-o)Z!>k1a`gkzY9>*x;~>wVi*KEiKb(IfO_#qh9)e$+x9w3i zT`Mu>w-Jx`m$*OX*ruIi)q>8Nh+C2pa|=<_5$xB>ln=p~si(oT}m=Y;nX571TsuLyQx#!)@o>rDMff&&k}`$H2p@NK=bF5~gj z$gaU9ZF0C1hz)@~lkS}V@L;)458de>Tjp_!L+Hcc0a3nH%|+fm#!WR3Gx8&5zQbj9HXo2r1?QfbTJW8-1*712rprUoXD&har%ygiegMA@#u9Do6jR&^_D|UD!5o9W)fB_ECMeCY*Z|8p)FLO z=ONS%xtPcC5PVqBxgENQ`TT=_pu|PBMoMlR-yVg446PQGM?kwY7)+z4QC3!8o1tz`|^}_0zeO5g1W9{tx5l5)6!syK1*8<+xz# z;HiRa;%6xvTx<|R_@ur%*(3@0UxbS;y6A*-ft9@?tl_Q0pPuFbLB!1RONr56Iq+*+ zzMY=4X?F{mMzY>oPv^u^vuhaW$YqdMP>p|f)7w`a8}EWT2Jddn=plySQ@FB(y7gQ-QzVet=f-*8dq$Fm-~Hc;XUCO5G#gD^l?eB^ZyajK7Ox;H=4 z6tM(N^5S=ysN3A#nD}M)2Uk;t;jc~LFd{GE&P(vP52W=I|@tF zH*?xA<~yAsSnTpz$D1P7UFO`}jGC;%kPdf$^zT8_r2(sxhO1q8S|t;7M)(XpIx47y zFu7MV_K^qSaD~j&YaAyIj7B@v84RkOS9*;YSRal9mjcohro6@d$0UEb#1xl_Z_FtzW^ zXu;`xHf*i7WpJ4KKl{s$fmhfqLYozGa*b+lnbb@+7m~F{Nk_h%Kcc7iMPGfnsI{%2 zCDS(IL%r6__5y|86pK8!wyrkSqsPmiA%8!RB?q&q>vP8jmbp8x4lcKB-I+x}vRb%m zen>U4YjXQ4r}-GJQOxMp3=r$sI6n9J2G$!XcfGg@)7EKIAzqy~CkkY5w29S8mo+-{ zZx9H0D7X0Llg~Ob#{!2t5@&p>42XFdoN9m3r0JH5;cJOcft8h&F=O5{?-g}BnAGyF z^jTD#q3tsRBG0f)s(pZDd@}h+v-%AirahS)4IzaRh zRQ2cmMsoKp^0q;NN4(E76Q@As#+J)ExoE?Z;|u+ig^v63T3T9+6?Z{~>8Y?kdPIhR zBrlXAIovam+hbtX*my8b!CU9tp89w+{qcvM30dqV=eh<)TdrCrIb7+Cr#QYA5EzuL zVARZUE!{8s^4}3d3f8$GFgRH6l$h0-D>4ejq3V~HR5ef;8uI;j>a2#A(D8yfmMg44 zPtU|bUu38O5I_w631gS*qMDT{5ekQER6!mr!OM$|C=W?xO}akml#)tKy+}+w_itlg ayqG1y*u)btx{=y9R+y4OPNg22R literal 0 HcmV?d00001 From d2cad31db4f20ba005c9777930beadd75000d907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=96=E9=83=BD=E7=88=B1=E6=8A=A4=E5=8A=A8=E7=89=A9?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A?= <87239270+1355873789@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:22:24 +0800 Subject: [PATCH 3/5] add pixtral avatar --- .../src/assets/images/models/pixtral.png | Bin 0 -> 3765 bytes .../src/assets/images/models/pixtral_dark.png | Bin 0 -> 915 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/renderer/src/assets/images/models/pixtral.png create mode 100644 src/renderer/src/assets/images/models/pixtral_dark.png diff --git a/src/renderer/src/assets/images/models/pixtral.png b/src/renderer/src/assets/images/models/pixtral.png new file mode 100644 index 0000000000000000000000000000000000000000..6c3ae9b162639d656db8ff1636efa2fb448fabe3 GIT binary patch literal 3765 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 m=Q#e6Fa3X0{EKpqt5nuP3GX145~ZoFRl z#8~ssox)kmDjEL0PJGLIz*LxnrO`ovQsT$fCy(C0e}6b{d-Ny&g6Dn5AAk7qW5qJJD;Hc#Qv zgXOte0zWdD8WjXMuoD}0X5RC*D*bgO;OW~BEV$Ky4M>>voo89m_VdClO%4hic!O;UnGxCuDa# zdGYgM!3`go!w*DX>)F`buix7`TXllEoyvIwp(?2`_cCsUE4+N?d;a6O)8Yx@8|UAx66^rdHdI8fB*2opy%-JIuOKCX0t&lA{E&VI%Wi$?!#yT83+00K`}KbLh*2~7Y#G(ph- literal 0 HcmV?d00001 From 39cf227e42edf085c5eb9ae8ae06a092ace3f99c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=96=E9=83=BD=E7=88=B1=E6=8A=A4=E5=8A=A8=E7=89=A9?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A?= <87239270+1355873789@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:26:04 +0800 Subject: [PATCH 4/5] Match the avatar for the Pixtral model. --- src/renderer/src/config/models.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/renderer/src/config/models.ts b/src/renderer/src/config/models.ts index 72ac370f..4e9ca65d 100644 --- a/src/renderer/src/config/models.ts +++ b/src/renderer/src/config/models.ts @@ -97,6 +97,8 @@ import NvidiaModelLogo from '@renderer/assets/images/models/nvidia.png' import NvidiaModelLogoDark from '@renderer/assets/images/models/nvidia_dark.png' import PalmModelLogo from '@renderer/assets/images/models/palm.png' import PalmModelLogoDark from '@renderer/assets/images/models/palm_dark.png' +import PixtralModelLogo from '@renderer/assets/images/models/pixtral.png' +import PixtralModelLogoDark from '@renderer/assets/images/models/pixtral_dark.png' import QwenModelLogo from '@renderer/assets/images/models/qwen.png' import QwenModelLogoDark from '@renderer/assets/images/models/qwen_dark.png' import RakutenaiModelLogo from '@renderer/assets/images/models/rakutenai.png' @@ -156,6 +158,7 @@ export function getModelLogo(modelId: string) { } const logoMap = { + pixtral: isLight ? PixtralModelLogo : PixtralModelLogoDark, jina: isLight ? JinaModelLogo : JinaModelLogoDark, abab: isLight ? MinimaxModelLogo : MinimaxModelLogoDark, 'o1-': isLight ? ChatGPTo1ModelLogo : ChatGPTo1ModelLogoDark, From 14c9cb60014906241aea50469e772c46213362f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=96=E9=83=BD=E7=88=B1=E6=8A=A4=E5=8A=A8=E7=89=A9?= =?UTF-8?q?=E5=8D=8F=E4=BC=9A?= <87239270+1355873789@users.noreply.github.com> Date: Sat, 7 Dec 2024 12:27:16 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=8E=86=E5=8F=B2=E6=B6=88=E6=81=AF?= =?UTF-8?q?=E6=87=92=E5=8A=A0=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 性能优化 --- package.json | 2 + .../src/pages/home/Messages/Messages.tsx | 120 ++++++++++++++---- yarn.lock | 29 +++++ 3 files changed, 126 insertions(+), 25 deletions(-) diff --git a/package.json b/package.json index 1bcf4e4e..cba4dfec 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "dependencies": { "@electron-toolkit/preload": "^3.0.0", "@electron-toolkit/utils": "^3.0.0", + "@types/react-infinite-scroll-component": "^5.0.0", "adm-zip": "^0.5.16", "docx": "^9.0.2", "electron-log": "^5.1.5", @@ -48,6 +49,7 @@ "html2canvas": "^1.4.1", "markdown-it": "^14.1.0", "officeparser": "^4.1.1", + "react-infinite-scroll-component": "^6.1.0", "webdav": "4.11.4" }, "devDependencies": { diff --git a/src/renderer/src/pages/home/Messages/Messages.tsx b/src/renderer/src/pages/home/Messages/Messages.tsx index a3ebf4fc..3bdfabb7 100644 --- a/src/renderer/src/pages/home/Messages/Messages.tsx +++ b/src/renderer/src/pages/home/Messages/Messages.tsx @@ -17,8 +17,10 @@ import { estimateHistoryTokens } from '@renderer/services/TokenService' import { Assistant, Message, Model, Topic } from '@renderer/types' import { captureScrollableDiv, runAsyncFunction, uuid } from '@renderer/utils' import { t } from 'i18next' -import { flatten, last, reverse, take } from 'lodash' +import { flatten, last, take } from 'lodash' import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react' +import InfiniteScroll from 'react-infinite-scroll-component' +import BeatLoader from 'react-spinners/BeatLoader' import styled from 'styled-components' import Suggestions from '../components/Suggestions' @@ -31,13 +33,53 @@ interface Props { setActiveTopic: (topic: Topic) => void } +interface LoaderProps { + $loading: boolean +} + +const LoaderContainer = styled.div` + display: flex; + justify-content: center; + padding: 10px; + width: 100%; + background: var(--color-background); + opacity: ${(props) => (props.$loading ? 1 : 0)}; + transition: opacity 0.3s ease; + pointer-events: none; +` + +const ScrollContainer = styled.div` + display: flex; + flex-direction: column-reverse; +` + +interface ContainerProps { + right?: boolean +} + +const Container = styled(Scrollbar)` + display: flex; + flex-direction: column-reverse; + padding: 10px 0; + padding-bottom: 20px; + overflow-x: hidden; + background-color: var(--color-background); +` + const Messages: FC = ({ assistant, topic, setActiveTopic }) => { const [messages, setMessages] = useState([]) + const [displayMessages, setDisplayMessages] = useState([]) + const [hasMore, setHasMore] = useState(true) + const [isLoadingMore, setIsLoadingMore] = useState(false) + const containerRef = useRef(null) + const messagesRef = useRef(messages) const { updateTopic, addTopic } = useAssistant(assistant.id) const { showTopics, topicPosition, showAssistants, enableTopicNaming } = useSettings() - const messagesRef = useRef(messages) + const INITIAL_MESSAGES_COUNT = 30 + const LOAD_MORE_COUNT = 20 + messagesRef.current = messages const maxWidth = useMemo(() => { @@ -158,7 +200,7 @@ const Messages: FC = ({ assistant, topic, setActiveTopic }) => { setActiveTopic(newTopic) autoRenameTopic() - // 由于复制了消息,消息中附带的文件的总数变了,需要更新 + // 由于复制了消���,消息中附带的文件的总数变了,需要更新 const filesArr = branchMessages.map((m) => m.files) const files = flatten(filesArr).filter(Boolean) files.map(async (f) => { @@ -197,7 +239,31 @@ const Messages: FC = ({ assistant, topic, setActiveTopic }) => { }) }, [assistant, messages]) - const memoizedMessages = useMemo(() => reverse([...messages]), [messages]) + // 初始化显示最新的消息 + useEffect(() => { + if (messages.length > 0) { + const reversedMessages = [...messages].reverse() + setDisplayMessages(reversedMessages.slice(0, INITIAL_MESSAGES_COUNT)) + setHasMore(messages.length > INITIAL_MESSAGES_COUNT) + } + }, [messages]) + + // 加载更多历史消息 + const loadMoreMessages = useCallback(() => { + if (!hasMore || isLoadingMore) return + + setIsLoadingMore(true) + + setTimeout(() => { + const currentLength = displayMessages.length + const reversedMessages = [...messages].reverse() + const moreMessages = reversedMessages.slice(currentLength, currentLength + LOAD_MORE_COUNT) + + setDisplayMessages((prev) => [...prev, ...moreMessages]) + setHasMore(currentLength + LOAD_MORE_COUNT < messages.length) + setIsLoadingMore(false) + }, 300) + }, [displayMessages, hasMore, isLoadingMore, messages]) return ( = ({ assistant, topic, setActiveTopic }) => { ref={containerRef} right={topicPosition === 'left'}> - {memoizedMessages.map((message, index) => ( - - ))} + + + + + + {displayMessages.map((message, index) => ( + + ))} + + ) } -const Container = styled(Scrollbar)` - display: flex; - flex-direction: column-reverse; - padding: 10px 0; - padding-bottom: 20px; - overflow-x: hidden; - background-color: var(--color-background); -` - export default Messages diff --git a/yarn.lock b/yarn.lock index 499c94c2..50c38fa2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2093,6 +2093,15 @@ __metadata: languageName: node linkType: hard +"@types/react-infinite-scroll-component@npm:^5.0.0": + version: 5.0.0 + resolution: "@types/react-infinite-scroll-component@npm:5.0.0" + dependencies: + react-infinite-scroll-component: "npm:*" + checksum: 10c0/257e7b2fc6ebf200ada409a5c21415c1a56157807636405f3329521cf36344a81afa87f992497747534453e48145b0d4f32ccee80814548b466a0d83dfa23eec + languageName: node + linkType: hard + "@types/react@npm:*, @types/react@npm:^18.2.48": version: 18.3.5 resolution: "@types/react@npm:18.3.5" @@ -2343,6 +2352,7 @@ __metadata: "@types/node": "npm:^18.19.9" "@types/react": "npm:^18.2.48" "@types/react-dom": "npm:^18.2.18" + "@types/react-infinite-scroll-component": "npm:^5.0.0" "@types/tinycolor2": "npm:^1" "@vitejs/plugin-react": "npm:^4.2.1" adm-zip: "npm:^0.5.16" @@ -2384,6 +2394,7 @@ __metadata: react-dom: "npm:^18.2.0" react-hotkeys-hook: "npm:^4.6.1" react-i18next: "npm:^14.1.2" + react-infinite-scroll-component: "npm:^6.1.0" react-markdown: "npm:^9.0.1" react-redux: "npm:^9.1.2" react-router: "npm:6" @@ -9965,6 +9976,17 @@ __metadata: languageName: node linkType: hard +"react-infinite-scroll-component@npm:*, react-infinite-scroll-component@npm:^6.1.0": + version: 6.1.0 + resolution: "react-infinite-scroll-component@npm:6.1.0" + dependencies: + throttle-debounce: "npm:^2.1.0" + peerDependencies: + react: ">=16.0.0" + checksum: 10c0/8de02f178ae861880dddbd0c882dc70b55e21737b87fe428140d81a2c5d13c5eeba8a4fc260b1e86e4c556fdea333d6babaed55a9e5987a42b181b2d92f69cd8 + languageName: node + linkType: hard + "react-is@npm:^16.13.1, react-is@npm:^16.7.0": version: 16.13.1 resolution: "react-is@npm:16.13.1" @@ -11546,6 +11568,13 @@ __metadata: languageName: node linkType: hard +"throttle-debounce@npm:^2.1.0": + version: 2.3.0 + resolution: "throttle-debounce@npm:2.3.0" + checksum: 10c0/41648e4cf46f935818af32ecac34f9876c618f24e300551cbe3a0ca2c5828cb8d2f9b73e6e1e2f8c64237f70fbc8c541f9b5c9114da70b33b1ed10ba4cc6b15f + languageName: node + linkType: hard + "throttle-debounce@npm:^5.0.0, throttle-debounce@npm:^5.0.2": version: 5.0.2 resolution: "throttle-debounce@npm:5.0.2"