feat: add model Provider GPUStack
This commit is contained in:
parent
d7cbba8f5b
commit
c7bd1918a9
14
src/renderer/src/assets/images/providers/gpustack.svg
Normal file
14
src/renderer/src/assets/images/providers/gpustack.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 20 KiB |
@ -1780,7 +1780,8 @@ export const SYSTEM_MODELS: Record<string, Model[]> = {
|
|||||||
name: 'DeepSeek V3',
|
name: 'DeepSeek V3',
|
||||||
group: 'DeepSeek'
|
group: 'DeepSeek'
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
gpustack: []
|
||||||
}
|
}
|
||||||
|
|
||||||
export const TEXT_TO_IMAGES_MODELS = [
|
export const TEXT_TO_IMAGES_MODELS = [
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import FireworksProviderLogo from '@renderer/assets/images/providers/fireworks.p
|
|||||||
import GiteeAIProviderLogo from '@renderer/assets/images/providers/gitee-ai.png'
|
import GiteeAIProviderLogo from '@renderer/assets/images/providers/gitee-ai.png'
|
||||||
import GithubProviderLogo from '@renderer/assets/images/providers/github.png'
|
import GithubProviderLogo from '@renderer/assets/images/providers/github.png'
|
||||||
import GoogleProviderLogo from '@renderer/assets/images/providers/google.png'
|
import GoogleProviderLogo from '@renderer/assets/images/providers/google.png'
|
||||||
|
import GPUStackProviderLogo from '@renderer/assets/images/providers/gpustack.svg'
|
||||||
import GraphRagProviderLogo from '@renderer/assets/images/providers/graph-rag.png'
|
import GraphRagProviderLogo from '@renderer/assets/images/providers/graph-rag.png'
|
||||||
import GrokProviderLogo from '@renderer/assets/images/providers/grok.png'
|
import GrokProviderLogo from '@renderer/assets/images/providers/grok.png'
|
||||||
import GroqProviderLogo from '@renderer/assets/images/providers/groq.png'
|
import GroqProviderLogo from '@renderer/assets/images/providers/groq.png'
|
||||||
@ -123,6 +124,8 @@ export function getProviderLogo(providerId: string) {
|
|||||||
return O3ProviderLogo
|
return O3ProviderLogo
|
||||||
case 'tencent-cloud-ti':
|
case 'tencent-cloud-ti':
|
||||||
return TencentCloudProviderLogo
|
return TencentCloudProviderLogo
|
||||||
|
case 'gpustack':
|
||||||
|
return GPUStackProviderLogo
|
||||||
default:
|
default:
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
@ -572,5 +575,15 @@ export const PROVIDER_CONFIG = {
|
|||||||
docs: 'https://cloud.tencent.com/document/product/1772',
|
docs: 'https://cloud.tencent.com/document/product/1772',
|
||||||
models: 'https://console.cloud.tencent.com/tione/v2/aimarket'
|
models: 'https://console.cloud.tencent.com/tione/v2/aimarket'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
gpustack: {
|
||||||
|
api: {
|
||||||
|
url: ''
|
||||||
|
},
|
||||||
|
websites: {
|
||||||
|
official: 'https://gpustack.ai/',
|
||||||
|
docs: 'https://docs.gpustack.ai/latest/',
|
||||||
|
models: 'https://docs.gpustack.ai/latest/overview/#supported-models'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/renderer/src/hooks/useGPUStack.ts
Normal file
18
src/renderer/src/hooks/useGPUStack.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import store, { useAppSelector } from '@renderer/store'
|
||||||
|
import { setGPUStackKeepAliveTime } from '@renderer/store/llm'
|
||||||
|
import { useDispatch } from 'react-redux'
|
||||||
|
|
||||||
|
export function useGPUStackSettings() {
|
||||||
|
const settings = useAppSelector((state) => state.llm.settings.gpustack)
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
|
||||||
|
return { ...settings, setKeepAliveTime: (time: number) => dispatch(setGPUStackKeepAliveTime(time)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGPUStackSettings() {
|
||||||
|
return store.getState().llm.settings.gpustack
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getGPUStackKeepAliveTime() {
|
||||||
|
return store.getState().llm.settings.gpustack.keepAliveTime + 'm'
|
||||||
|
}
|
||||||
@ -561,6 +561,12 @@
|
|||||||
},
|
},
|
||||||
"title": "PlantUML Diagram"
|
"title": "PlantUML Diagram"
|
||||||
},
|
},
|
||||||
|
"gpustack": {
|
||||||
|
"keep_alive_time.description": "The time in minutes to keep the connection alive, default is 5 minutes.",
|
||||||
|
"keep_alive_time.placeholder": "Minutes",
|
||||||
|
"keep_alive_time.title": "Keep Alive Time",
|
||||||
|
"title": "GPUStack"
|
||||||
|
},
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"explanation": "Explain this concept to me",
|
"explanation": "Explain this concept to me",
|
||||||
"summarize": "Summarize this text",
|
"summarize": "Summarize this text",
|
||||||
@ -608,7 +614,8 @@
|
|||||||
"xirang": "State Cloud Xirang",
|
"xirang": "State Cloud Xirang",
|
||||||
"yi": "Yi",
|
"yi": "Yi",
|
||||||
"zhinao": "360AI",
|
"zhinao": "360AI",
|
||||||
"zhipu": "ZHIPU AI"
|
"zhipu": "ZHIPU AI",
|
||||||
|
"gpustack": "GPUStack"
|
||||||
},
|
},
|
||||||
"restore": {
|
"restore": {
|
||||||
"confirm": "Are you sure you want to restore data?",
|
"confirm": "Are you sure you want to restore data?",
|
||||||
|
|||||||
@ -561,6 +561,12 @@
|
|||||||
},
|
},
|
||||||
"title": "PlantUML 図表"
|
"title": "PlantUML 図表"
|
||||||
},
|
},
|
||||||
|
"gpustack": {
|
||||||
|
"keep_alive_time.description": "モデルがメモリに保持される時間(デフォルト:5分)",
|
||||||
|
"keep_alive_time.placeholder": "分",
|
||||||
|
"keep_alive_time.title": "保持時間",
|
||||||
|
"title": "GPUStack"
|
||||||
|
},
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"explanation": "この概念を説明してください",
|
"explanation": "この概念を説明してください",
|
||||||
"summarize": "このテキストを要約してください",
|
"summarize": "このテキストを要約してください",
|
||||||
@ -608,7 +614,8 @@
|
|||||||
"xirang": "天翼クラウド 息壤",
|
"xirang": "天翼クラウド 息壤",
|
||||||
"yi": "零一万物",
|
"yi": "零一万物",
|
||||||
"zhinao": "360智脳",
|
"zhinao": "360智脳",
|
||||||
"zhipu": "智譜AI"
|
"zhipu": "智譜AI",
|
||||||
|
"gpustack": "GPUStack"
|
||||||
},
|
},
|
||||||
"restore": {
|
"restore": {
|
||||||
"confirm": "データを復元しますか?",
|
"confirm": "データを復元しますか?",
|
||||||
|
|||||||
@ -388,6 +388,12 @@
|
|||||||
},
|
},
|
||||||
"title": "Диаграмма Mermaid"
|
"title": "Диаграмма Mermaid"
|
||||||
},
|
},
|
||||||
|
"gpustack": {
|
||||||
|
"keep_alive_time.description": "Время в минутах, в течение которого модель остается активной, по умолчанию 5 минут.",
|
||||||
|
"keep_alive_time.placeholder": "Минуты",
|
||||||
|
"keep_alive_time.title": "Время жизни модели",
|
||||||
|
"title": "GPUStack"
|
||||||
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"api.check.model.title": "Выберите модель для проверки",
|
"api.check.model.title": "Выберите модель для проверки",
|
||||||
"api.connection.failed": "Соединение не удалось",
|
"api.connection.failed": "Соединение не удалось",
|
||||||
@ -608,7 +614,8 @@
|
|||||||
"xirang": "State Cloud Xirang",
|
"xirang": "State Cloud Xirang",
|
||||||
"yi": "Yi",
|
"yi": "Yi",
|
||||||
"zhinao": "360AI",
|
"zhinao": "360AI",
|
||||||
"zhipu": "ZHIPU AI"
|
"zhipu": "ZHIPU AI",
|
||||||
|
"gpustack": "GPUStack"
|
||||||
},
|
},
|
||||||
"restore": {
|
"restore": {
|
||||||
"confirm": "Вы уверены, что хотите восстановить данные?",
|
"confirm": "Вы уверены, что хотите восстановить данные?",
|
||||||
|
|||||||
@ -608,7 +608,8 @@
|
|||||||
"xirang": "天翼云息壤",
|
"xirang": "天翼云息壤",
|
||||||
"yi": "零一万物",
|
"yi": "零一万物",
|
||||||
"zhinao": "360智脑",
|
"zhinao": "360智脑",
|
||||||
"zhipu": "智谱AI"
|
"zhipu": "智谱AI",
|
||||||
|
"gpustack": "GPUStack"
|
||||||
},
|
},
|
||||||
"restore": {
|
"restore": {
|
||||||
"confirm": "确定要恢复数据吗?",
|
"confirm": "确定要恢复数据吗?",
|
||||||
@ -624,6 +625,12 @@
|
|||||||
},
|
},
|
||||||
"title": "数据恢复"
|
"title": "数据恢复"
|
||||||
},
|
},
|
||||||
|
"gpustack": {
|
||||||
|
"keep_alive_time.description": "模型在内存中保持的时间(默认:5分钟)",
|
||||||
|
"keep_alive_time.placeholder": "分钟",
|
||||||
|
"keep_alive_time.title": "保持活跃时间",
|
||||||
|
"title": "GPUStack"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"about": "关于我们",
|
"about": "关于我们",
|
||||||
"about.checkingUpdate": "正在检查更新...",
|
"about.checkingUpdate": "正在检查更新...",
|
||||||
|
|||||||
@ -608,7 +608,8 @@
|
|||||||
"xirang": "天翼雲息壤",
|
"xirang": "天翼雲息壤",
|
||||||
"yi": "零一萬物",
|
"yi": "零一萬物",
|
||||||
"zhinao": "360 智腦",
|
"zhinao": "360 智腦",
|
||||||
"zhipu": "智譜 AI"
|
"zhipu": "智譜 AI",
|
||||||
|
"gpustack": "GPUStack"
|
||||||
},
|
},
|
||||||
"restore": {
|
"restore": {
|
||||||
"confirm": "確定要復原資料嗎?",
|
"confirm": "確定要復原資料嗎?",
|
||||||
@ -624,6 +625,12 @@
|
|||||||
},
|
},
|
||||||
"title": "資料復原"
|
"title": "資料復原"
|
||||||
},
|
},
|
||||||
|
"gpustack": {
|
||||||
|
"keep_alive_time.description": "模型在記憶體中保持的時間(預設為 5 分鐘)。",
|
||||||
|
"keep_alive_time.placeholder": "分鐘",
|
||||||
|
"keep_alive_time.title": "保持活躍時間",
|
||||||
|
"title": "GPUStack"
|
||||||
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"about": "關於與回饋",
|
"about": "關於與回饋",
|
||||||
"about.checkingUpdate": "正在檢查更新...",
|
"about.checkingUpdate": "正在檢查更新...",
|
||||||
|
|||||||
@ -0,0 +1,34 @@
|
|||||||
|
import { useGPUStackSettings } from '@renderer/hooks/useGPUStack'
|
||||||
|
import { InputNumber } from 'antd'
|
||||||
|
import { FC, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
|
import { SettingHelpText, SettingHelpTextRow, SettingSubtitle } from '..'
|
||||||
|
|
||||||
|
const GPUStackSettings: FC = () => {
|
||||||
|
const { keepAliveTime, setKeepAliveTime } = useGPUStackSettings()
|
||||||
|
const [keepAliveMinutes, setKeepAliveMinutes] = useState(keepAliveTime)
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Container>
|
||||||
|
<SettingSubtitle style={{ marginBottom: 5 }}>{t('gpustack.keep_alive_time.title')}</SettingSubtitle>
|
||||||
|
<InputNumber
|
||||||
|
style={{ width: '100%' }}
|
||||||
|
value={keepAliveMinutes}
|
||||||
|
onChange={(e) => setKeepAliveMinutes(Number(e))}
|
||||||
|
onBlur={() => setKeepAliveTime(keepAliveMinutes)}
|
||||||
|
suffix={t('gpustack.keep_alive_time.placeholder')}
|
||||||
|
step={5}
|
||||||
|
/>
|
||||||
|
<SettingHelpTextRow>
|
||||||
|
<SettingHelpText>{t('gpustack.keep_alive_time.description')}</SettingHelpText>
|
||||||
|
</SettingHelpTextRow>
|
||||||
|
</Container>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Container = styled.div``
|
||||||
|
|
||||||
|
export default GPUStackSettings
|
||||||
@ -28,6 +28,7 @@ import {
|
|||||||
SettingTitle
|
SettingTitle
|
||||||
} from '..'
|
} from '..'
|
||||||
import ApiCheckPopup from './ApiCheckPopup'
|
import ApiCheckPopup from './ApiCheckPopup'
|
||||||
|
import GPUStackSettings from './GPUStackSettings'
|
||||||
import GraphRAGSettings from './GraphRAGSettings'
|
import GraphRAGSettings from './GraphRAGSettings'
|
||||||
import HealthCheckPopup from './HealthCheckPopup'
|
import HealthCheckPopup from './HealthCheckPopup'
|
||||||
import LMStudioSettings from './LMStudioSettings'
|
import LMStudioSettings from './LMStudioSettings'
|
||||||
@ -345,6 +346,7 @@ const ProviderSetting: FC<Props> = ({ provider: _provider }) => {
|
|||||||
)}
|
)}
|
||||||
{provider.id === 'ollama' && <OllamSettings />}
|
{provider.id === 'ollama' && <OllamSettings />}
|
||||||
{provider.id === 'lmstudio' && <LMStudioSettings />}
|
{provider.id === 'lmstudio' && <LMStudioSettings />}
|
||||||
|
{provider.id === 'gpustack' && <GPUStackSettings />}
|
||||||
{provider.id === 'graphrag-kylin-mountain' && provider.models.length > 0 && (
|
{provider.id === 'graphrag-kylin-mountain' && provider.models.length > 0 && (
|
||||||
<GraphRAGSettings provider={provider} />
|
<GraphRAGSettings provider={provider} />
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -36,7 +36,7 @@ const persistedReducer = persistReducer(
|
|||||||
{
|
{
|
||||||
key: 'cherry-studio',
|
key: 'cherry-studio',
|
||||||
storage,
|
storage,
|
||||||
version: 78,
|
version: 79,
|
||||||
blacklist: ['runtime', 'messages'],
|
blacklist: ['runtime', 'messages'],
|
||||||
migrate
|
migrate
|
||||||
},
|
},
|
||||||
|
|||||||
@ -11,6 +11,9 @@ type LlmSettings = {
|
|||||||
lmstudio: {
|
lmstudio: {
|
||||||
keepAliveTime: number
|
keepAliveTime: number
|
||||||
}
|
}
|
||||||
|
gpustack: {
|
||||||
|
keepAliveTime: number
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LlmState {
|
export interface LlmState {
|
||||||
@ -426,6 +429,16 @@ const initialState: LlmState = {
|
|||||||
models: SYSTEM_MODELS['tencent-cloud-ti'],
|
models: SYSTEM_MODELS['tencent-cloud-ti'],
|
||||||
isSystem: true,
|
isSystem: true,
|
||||||
enabled: false
|
enabled: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'gpustack',
|
||||||
|
name: 'GPUStack',
|
||||||
|
type: 'openai',
|
||||||
|
apiKey: '',
|
||||||
|
apiHost: '',
|
||||||
|
models: SYSTEM_MODELS.gpustack,
|
||||||
|
isSystem: true,
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
settings: {
|
settings: {
|
||||||
@ -434,6 +447,9 @@ const initialState: LlmState = {
|
|||||||
},
|
},
|
||||||
lmstudio: {
|
lmstudio: {
|
||||||
keepAliveTime: 0
|
keepAliveTime: 0
|
||||||
|
},
|
||||||
|
gpustack: {
|
||||||
|
keepAliveTime: 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,6 +478,9 @@ const getIntegratedInitialState = () => {
|
|||||||
},
|
},
|
||||||
lmstudio: {
|
lmstudio: {
|
||||||
keepAliveTime: 3600
|
keepAliveTime: 3600
|
||||||
|
},
|
||||||
|
gpustack: {
|
||||||
|
keepAliveTime: 3600
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} as LlmState
|
} as LlmState
|
||||||
@ -534,6 +553,9 @@ const settingsSlice = createSlice({
|
|||||||
setLMStudioKeepAliveTime: (state, action: PayloadAction<number>) => {
|
setLMStudioKeepAliveTime: (state, action: PayloadAction<number>) => {
|
||||||
state.settings.lmstudio.keepAliveTime = action.payload
|
state.settings.lmstudio.keepAliveTime = action.payload
|
||||||
},
|
},
|
||||||
|
setGPUStackKeepAliveTime: (state, action: PayloadAction<number>) => {
|
||||||
|
state.settings.gpustack.keepAliveTime = action.payload
|
||||||
|
},
|
||||||
updateModel: (
|
updateModel: (
|
||||||
state,
|
state,
|
||||||
action: PayloadAction<{
|
action: PayloadAction<{
|
||||||
@ -564,6 +586,7 @@ export const {
|
|||||||
setTranslateModel,
|
setTranslateModel,
|
||||||
setOllamaKeepAliveTime,
|
setOllamaKeepAliveTime,
|
||||||
setLMStudioKeepAliveTime,
|
setLMStudioKeepAliveTime,
|
||||||
|
setGPUStackKeepAliveTime,
|
||||||
updateModel
|
updateModel
|
||||||
} = settingsSlice.actions
|
} = settingsSlice.actions
|
||||||
|
|
||||||
|
|||||||
@ -1243,6 +1243,19 @@ const migrateConfig = {
|
|||||||
state.llm.providers = moveProvider(state.llm.providers, 'infini', 10)
|
state.llm.providers = moveProvider(state.llm.providers, 'infini', 10)
|
||||||
removeMiniAppIconsFromState(state)
|
removeMiniAppIconsFromState(state)
|
||||||
return state
|
return state
|
||||||
|
},
|
||||||
|
'79': (state: RootState) => {
|
||||||
|
state.llm.providers.push({
|
||||||
|
id: 'gpustack',
|
||||||
|
name: 'GPUStack',
|
||||||
|
type: 'openai',
|
||||||
|
apiKey: '',
|
||||||
|
apiHost: '',
|
||||||
|
models: SYSTEM_MODELS.gpustack,
|
||||||
|
isSystem: true,
|
||||||
|
enabled: false
|
||||||
|
})
|
||||||
|
return state
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user