From e7de1896ea40e9a2dbbd04ded1296ed5fc44fb98 Mon Sep 17 00:00:00 2001 From: jialin Date: Mon, 23 Dec 2024 16:32:15 +0800 Subject: [PATCH] chore: display the direct command in add worker --- config/proxy.ts | 15 +--- src/app.tsx | 11 ++- src/assets/styles/driver.less | 9 ++ src/atoms/user.ts | 4 +- src/components/radio-buttons/index.less | 5 +- src/components/radio-buttons/index.tsx | 2 +- src/config/driver-config.ts | 5 ++ src/global.less | 1 + src/hooks/use-driver.ts | 2 +- src/locales/en-US/common.ts | 3 +- src/locales/en-US/models.ts | 10 ++- src/locales/en-US/playground.ts | 4 +- src/locales/en-US/resources.ts | 6 +- src/locales/zh-CN/common.ts | 3 +- src/locales/zh-CN/models.ts | 9 +- src/locales/zh-CN/playground.ts | 4 +- src/locales/zh-CN/resources.ts | 5 +- .../llmodels/components/advance-config.tsx | 15 ++++ src/pages/llmodels/components/data-form.tsx | 78 ++++++++++------- .../llmodels/components/deploy-modal.tsx | 12 +-- .../llmodels/components/instance-item.tsx | 8 +- .../llmodels/components/search-model.tsx | 15 +++- .../llmodels/components/search-result.tsx | 2 +- src/pages/llmodels/components/table-list.tsx | 2 +- src/pages/llmodels/config/index.ts | 8 ++ src/pages/llmodels/config/llama-config.ts | 4 + src/pages/llmodels/style/search-result.less | 11 +++ src/pages/resources/components/add-worker.tsx | 73 ++++++---------- .../components/container-install.tsx | 86 +++++++++++++++++++ .../resources/components/script-install.tsx | 40 +++++++++ .../components/styles/installation.less | 13 +++ src/pages/resources/config/index.ts | 19 ++-- 32 files changed, 359 insertions(+), 125 deletions(-) create mode 100644 src/assets/styles/driver.less create mode 100644 src/config/driver-config.ts create mode 100644 src/pages/resources/components/container-install.tsx create mode 100644 src/pages/resources/components/script-install.tsx create mode 100644 src/pages/resources/components/styles/installation.less diff --git a/config/proxy.ts b/config/proxy.ts index 6c09cb91..6d13e9e0 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -20,18 +20,9 @@ export default function createProxyTable(target?: string) { ws: true, pathRewrite: (pth: string) => pth.replace(`/^/${api}`, `/${api}`), // onProxyRes: (proxyRes: any, req: any, res: any) => { - // console.log('proxyRes=====', req); - - // proxyRes.on('data', (chunk: any) => { - // res.write(chunk); - // }); - - // proxyRes.on('end', () => { - // res.end(); - // }); - - // proxyRes.on('error', (err: any) => { - // res.status(500).end('Stream error'); + // console.log('headers=========', { + // res: proxyRes.headers, + // req: req.headers // }); // }, headers: { diff --git a/src/app.tsx b/src/app.tsx index c07bfa11..60ea122c 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -20,7 +20,10 @@ export async function getInitialState(): Promise<{ const getUpdateCheck = async () => { try { const data = await updateCheck(); - setAtomStorage(UpdateCheckAtom, data); + + setAtomStorage(UpdateCheckAtom, { + ...data + }); return data; } catch (error) { console.error('updateCheck error', error); @@ -45,7 +48,11 @@ export async function getInitialState(): Promise<{ const getAppVersionInfo = async () => { try { const data = await queryVersionInfo(); - setAtomStorage(GPUStackVersionAtom, data); + const isProduction = data.version?.indexOf('0.0.0') === -1; + setAtomStorage(GPUStackVersionAtom, { + ...data, + isProduction + }); } catch (error) { console.error('queryVersionInfo error', error); } diff --git a/src/assets/styles/driver.less b/src/assets/styles/driver.less new file mode 100644 index 00000000..ed05f57d --- /dev/null +++ b/src/assets/styles/driver.less @@ -0,0 +1,9 @@ +.driver-popover { + color: var(--ant-color-text); + + .driver-popover-title { + font-size: 16px; + font-weight: var(--font-weight-bold); + color: var(--ant-color-text); + } +} diff --git a/src/atoms/user.ts b/src/atoms/user.ts index 4e88c34e..e84ed294 100644 --- a/src/atoms/user.ts +++ b/src/atoms/user.ts @@ -6,9 +6,11 @@ export const userAtom = atomWithStorage('userInfo', null); export const GPUStackVersionAtom = atom<{ version: string; git_commit: string; + isProduction: boolean; }>({ version: '', - git_commit: '' + git_commit: '', + isProduction: false }); export const UpdateCheckAtom = atom<{ diff --git a/src/components/radio-buttons/index.less b/src/components/radio-buttons/index.less index 7ef31b91..ee4bed59 100644 --- a/src/components/radio-buttons/index.less +++ b/src/components/radio-buttons/index.less @@ -4,10 +4,9 @@ justify-content: center; align-items: center; font-size: var(--font-size-base); - padding: 2px; border-radius: var(--border-radius-base); - height: 40px; - width: 40px; + height: 32px; + padding: 0 8px; border: 1px solid var(--ant-color-border); cursor: pointer; diff --git a/src/components/radio-buttons/index.tsx b/src/components/radio-buttons/index.tsx index ea98e4e4..c228b9ee 100644 --- a/src/components/radio-buttons/index.tsx +++ b/src/components/radio-buttons/index.tsx @@ -16,7 +16,7 @@ const RadioButtons: React.FC = (props) => { {options.map((option) => ( onChange(option.value)} + onClick={() => onChange({ target: { value: option.value } } as any)} className={classNames('item', { active: value === option.value })} > {option.label} diff --git a/src/config/driver-config.ts b/src/config/driver-config.ts new file mode 100644 index 00000000..dfce6662 --- /dev/null +++ b/src/config/driver-config.ts @@ -0,0 +1,5 @@ +const driverIDMap = { + deployModel: 'deploy-model' +}; + +const driverConfig = {}; diff --git a/src/global.less b/src/global.less index 27b7b6d8..1efc8b85 100644 --- a/src/global.less +++ b/src/global.less @@ -1,5 +1,6 @@ @import url('src/assets/styles/common.less'); @import url('src/assets/styles/menu.less'); +@import url('src/assets/styles/driver.less'); html { --font-family: 'noto sans', sans-serif; diff --git a/src/hooks/use-driver.ts b/src/hooks/use-driver.ts index e5b1718f..c923d975 100644 --- a/src/hooks/use-driver.ts +++ b/src/hooks/use-driver.ts @@ -2,7 +2,7 @@ import { useIntl } from '@umijs/max'; import { driver, type Config } from 'driver.js'; import { useEffect, useRef } from 'react'; -export const useDriver = (config?: Config) => { +export const useDriver = (config?: Config & { id: string }) => { const intl = useIntl(); const driverRef = useRef(null); diff --git a/src/locales/en-US/common.ts b/src/locales/en-US/common.ts index 7605ffbc..87ff631f 100644 --- a/src/locales/en-US/common.ts +++ b/src/locales/en-US/common.ts @@ -212,5 +212,6 @@ export default { 'common.text.latest': 'Latest', 'common.text.new': 'New', 'common.text.changelog': 'Release Notes', - 'common.button.recreate': 'Recreate' + 'common.button.recreate': 'Recreate', + 'common.button.delrecreate': 'Delete (Recreate)' }; diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index 178ad906..b1be9daf 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -78,5 +78,13 @@ export default { 'models.form.backendVersion': 'Backend Version', 'models.form.backendVersion.tips': 'Pin a specific version to keep the backend stable across GPUStack upgrades.', - 'models.form.gpuselector': 'GPU Selector' + 'models.form.gpuselector': 'GPU Selector', + 'models.form.backend.llamabox': + 'llama-box: For GGUF format models, supports Linux, macOS, and Windows.', + 'models.form.backend.vllm': + 'vLLM: For non-GGUF format models, supports x86 Linux only.', + 'models.form.backend.voxbox': 'vox-box: For non-GGUF format audio models.', + 'models.form.search.gguftips': + 'GGUF format is required for Mac and Windows compatibility.', + 'models.form.button.addlabel': 'Add Label' }; diff --git a/src/locales/en-US/playground.ts b/src/locales/en-US/playground.ts index 9a9704a7..493382da 100644 --- a/src/locales/en-US/playground.ts +++ b/src/locales/en-US/playground.ts @@ -97,8 +97,8 @@ export default { 'playground.audio.button.generate': 'Generate Text Content', 'playground.multiple.on': 'Enable', 'playground.multiple.off': 'Disable', - 'playground.image.params.sampler': 'Sampler', - 'playground.image.params.schedule': 'Scheduler', + 'playground.image.params.sampler': 'Sample Method', + 'playground.image.params.schedule': 'Schedule Method', 'playground.image.params.samplerSteps': 'Sampling Steps', 'playground.image.params.seed': 'Seed', 'playground.image.params.randomseed': 'Random Seed', diff --git a/src/locales/en-US/resources.ts b/src/locales/en-US/resources.ts index 14ad87f7..8bf9273a 100644 --- a/src/locales/en-US/resources.ts +++ b/src/locales/en-US/resources.ts @@ -46,5 +46,9 @@ export default { 'resources.worker.add.step2.tips': 'Note: mytoken is the token obtained in the first step.', 'resources.worker.add.step3': - 'Refresh workers list, you will see the new worker.' + 'After success, refresh the workers list to see the new worker.', + 'resources.worker.container.supported': 'Do not support windows.', + 'resources.worker.current.version': 'Current version is {version}.', + 'resources.worker.select.command': + 'Select a label to generate the command and copy it using the copy button.' }; diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index 147443c6..a631e2d6 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -205,5 +205,6 @@ export default { 'common.text.latest': '最新', 'common.text.new': '新', 'common.text.changelog': '更新日志', - 'common.button.recreate': '重新创建' + 'common.button.recreate': '重新创建', + 'common.button.delrecreate': '删除(重建)' }; diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index 0af4a684..002999ef 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -75,5 +75,12 @@ export default { 'models.form.backendVersion': '后端版本', 'models.form.backendVersion.tips': '固定指定版本以保持后端在 GPUStack 升级过程中的稳定性', - 'models.form.gpuselector': 'GPU 选择器' + 'models.form.gpuselector': 'GPU 选择器', + 'models.form.backend.llamabox': + 'llama-box: 用于 GGUF 格式模型,支持 Linux, macOS 和 Windows', + 'models.form.backend.vllm': 'vLLM: 用于非 GGUF 格式模型,仅支持 x86 Linux', + 'models.form.backend.voxbox': 'vox-box: 用于非 GGUF 格式的音频模型', + 'models.form.search.gguftips': + 'Mac 和 Windows 需要使用 GGUF 格式以确保兼容性', + 'models.form.button.addlabel': '添加标签' }; diff --git a/src/locales/zh-CN/playground.ts b/src/locales/zh-CN/playground.ts index 7dde7eae..05619232 100644 --- a/src/locales/zh-CN/playground.ts +++ b/src/locales/zh-CN/playground.ts @@ -95,8 +95,8 @@ export default { 'playground.multiple.on': '开启', 'playground.multiple.off': '关闭', 'playground.image.params.sampler': '采样方法', - 'playground.image.params.schedule': '调度器', - 'playground.image.params.samplerSteps': '迭代步数', + 'playground.image.params.schedule': '调度方法', + 'playground.image.params.samplerSteps': '采样步数', 'playground.image.params.seed': '种子', 'playground.image.params.randomseed': '随机种子', 'playground.image.params.negativePrompt': '负向提示', diff --git a/src/locales/zh-CN/resources.ts b/src/locales/zh-CN/resources.ts index 27895563..c7213d67 100644 --- a/src/locales/zh-CN/resources.ts +++ b/src/locales/zh-CN/resources.ts @@ -45,5 +45,8 @@ export default { 'resources.worker.add.step2': '注册 Worker', 'resources.worker.add.step2.tips': '注意:mytoken 为第一步获取到的 Token', - 'resources.worker.add.step3': '刷新 workers 列表,可以看到新添加的 worker' + 'resources.worker.add.step3': '成功后,刷新 worker 列表即可看到新的 worker', + 'resources.worker.container.supported': '不支持 Windows', + 'resources.worker.current.version': '当前版本为 {version}', + 'resources.worker.select.command': '选择一个标签生成命令并使用复制按钮复制' }; diff --git a/src/pages/llmodels/components/advance-config.tsx b/src/pages/llmodels/components/advance-config.tsx index d8d6408f..147e1ba7 100644 --- a/src/pages/llmodels/components/advance-config.tsx +++ b/src/pages/llmodels/components/advance-config.tsx @@ -153,6 +153,21 @@ const AdvanceConfig: React.FC = (props) => { const collapseItems = useMemo(() => { const children = ( <> + {/* name="labels"> + + */} = forwardRef((props, ref) => { min={0} > - - +
+ +
+ 1.{' '} + {intl.formatMessage({ id: 'models.form.backend.llamabox' })} +
+
+ 2. {intl.formatMessage({ id: 'models.form.backend.vllm' })} +
+
+ 3. {intl.formatMessage({ id: 'models.form.backend.voxbox' })} +
+
} - ]} - disabled={ - action === PageAction.EDIT && - props.source !== modelSourceMap.local_path_value - } - >
+ options={[ + { + label: `llama-box`, + value: backendOptionsMap.llamaBox, + disabled: + props.source === modelSourceMap.local_path_value + ? false + : !isGGUF + }, + { + label: 'vLLM', + value: backendOptionsMap.vllm, + disabled: + props.source === modelSourceMap.local_path_value + ? false + : isGGUF + }, + { + label: 'vox-box', + value: backendOptionsMap.voxBox, + disabled: props.source === modelSourceMap.ollama_library_value + } + ]} + disabled={ + action === PageAction.EDIT && + props.source !== modelSourceMap.local_path_value + } + > +
name="description"> = (props) => { modelSourceMap.huggingface_value, modelSourceMap.modelscope_value ]; - const { start } = useDriver({ - steps - }); + // const { start } = useDriver({ + // steps, + // id: 'deploy-model' + // }); const form = useRef({}); const intl = useIntl(); const [selectedModel, setSelectedModel] = useState({}); @@ -128,7 +128,9 @@ const AddModal: React.FC = (props) => { // useEffect(() => { // if (open && loadfinish) { - // start(); + // setTimeout(() => { + // start(); + // }, 1000); // } // }, [loadfinish, open]); diff --git a/src/pages/llmodels/components/instance-item.tsx b/src/pages/llmodels/components/instance-item.tsx index 5c56b962..f0bc1867 100644 --- a/src/pages/llmodels/components/instance-item.tsx +++ b/src/pages/llmodels/components/instance-item.tsx @@ -8,8 +8,8 @@ import { ListItem as WorkerListItem } from '@/pages/resources/config/types'; import { + DeleteOutlined, FieldTimeOutlined, - FileSyncOutlined, InfoCircleOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; @@ -71,12 +71,12 @@ const InstanceItem: React.FC = ({ icon: }, { - label: 'common.button.recreate', + label: 'common.button.delrecreate', key: 'delete', props: { - danger: false + danger: true }, - icon: + icon: } ]; diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx index 09a49da1..7d6082ce 100644 --- a/src/pages/llmodels/components/search-model.tsx +++ b/src/pages/llmodels/components/search-model.tsx @@ -1,4 +1,8 @@ -import { BulbOutlined, InfoCircleOutlined } from '@ant-design/icons'; +import { + BulbOutlined, + QuestionCircleOutlined, + WarningOutlined +} from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Checkbox, Select, Tooltip } from 'antd'; import _ from 'lodash'; @@ -233,6 +237,12 @@ const SearchModel: React.FC = (props) => { onChange={handleSearchInputChange} modelSource={modelSource} > +
+ + + {intl.formatMessage({ id: 'models.form.search.gguftips' })} + +
@@ -268,7 +278,7 @@ const SearchModel: React.FC = (props) => { } > GGUF - + @@ -318,6 +328,7 @@ const SearchModel: React.FC = (props) => {
)} + { = (props) => { ); }; return ( - +
diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index 24f6ad3e..f080b191 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -449,7 +449,7 @@ const Models: React.FC = ({ const handleDeleteInstace = (row: any, list: ModelInstanceListItem[]) => { modalRef.current.show({ content: 'models.instances', - okText: 'common.button.recreate', + okText: 'common.button.delrecreate', name: row.name, async onOk() { await deleteModelInstance(row.id); diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index 67dda5d3..46c8c444 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -345,3 +345,11 @@ export const getVllmCliArgs = (inputString: string) => { return result; }; + +export const modelLabels = [ + { label: 'Image', value: 'image_only' }, + { label: 'Text-to-speech', value: 'text_to_speech' }, + { label: 'Speech-to-text', value: 'speech_to_text' }, + { label: 'reranker', value: 'reranker' }, + { label: 'Embedding', value: 'embedding_only' } +]; diff --git a/src/pages/llmodels/config/llama-config.ts b/src/pages/llmodels/config/llama-config.ts index a6e908f1..53bb7cfa 100644 --- a/src/pages/llmodels/config/llama-config.ts +++ b/src/pages/llmodels/config/llama-config.ts @@ -104,6 +104,10 @@ const options = [ { label: '--image-no-vae-tiling', value: '--image-no-vae-tiling' + }, + { + label: '--mmproj', + value: '--mmproj' } ]; diff --git a/src/pages/llmodels/style/search-result.less b/src/pages/llmodels/style/search-result.less index c93700ac..5141a808 100644 --- a/src/pages/llmodels/style/search-result.less +++ b/src/pages/llmodels/style/search-result.less @@ -8,6 +8,17 @@ // height: calc(100vh - 194px); } +.gguf-tips { + display: flex; + align-items: center; + padding: 8px 0; + color: var(--ant-color-text-secondary); + + .warning { + color: var(--ant-color-warning); + } +} + .search-bar { left: 0; right: 0; diff --git a/src/pages/resources/components/add-worker.tsx b/src/pages/resources/components/add-worker.tsx index 1b01a7dc..0d9228c9 100644 --- a/src/pages/resources/components/add-worker.tsx +++ b/src/pages/resources/components/add-worker.tsx @@ -1,8 +1,8 @@ -import HighlightCode from '@/components/highlight-code'; import { useIntl } from '@umijs/max'; -import { Modal } from 'antd'; +import { Modal, Tabs, TabsProps } from 'antd'; import React from 'react'; -import { addWorkerGuide } from '../config'; +import ContainerInstall from './container-install'; +import ScriptInstall from './script-install'; type ViewModalProps = { open: boolean; @@ -12,8 +12,21 @@ type ViewModalProps = { const AddWorker: React.FC = (props) => { const { open, onCancel } = props || {}; const intl = useIntl(); + const [token, setToken] = React.useState(''); + const [activeKey, setActiveKey] = React.useState('script'); - const origin = window.location.origin; + const items: TabsProps['items'] = [ + { + key: 'script', + label: 'Script Installation', + children: + }, + { + key: 'container', + label: 'Container Installation', + children: + } + ]; return ( = (props) => { maskClosable={false} keyboard={false} width={600} + styles={{ + body: { + height: 310 + } + }} footer={null} > -
-

1. {intl.formatMessage({ id: 'resources.worker.add.step1' })}

-

{intl.formatMessage({ id: 'resources.worker.linuxormaxos' })}

- -

Windows

- -

- 2. {intl.formatMessage({ id: 'resources.worker.add.step2' })}{' '} - -

-

{intl.formatMessage({ id: 'resources.worker.linuxormaxos' })}

- -

Windows

- -

Docker

- -

3. {intl.formatMessage({ id: 'resources.worker.add.step3' })}

-
+ setActiveKey(key)} + >
); }; diff --git a/src/pages/resources/components/container-install.tsx b/src/pages/resources/components/container-install.tsx new file mode 100644 index 00000000..8f7dae13 --- /dev/null +++ b/src/pages/resources/components/container-install.tsx @@ -0,0 +1,86 @@ +import { GPUStackVersionAtom } from '@/atoms/user'; +import { getAtomStorage } from '@/atoms/utils'; +import HighlightCode from '@/components/highlight-code'; +import { BulbOutlined, WarningOutlined } from '@ant-design/icons'; +import { useIntl } from '@umijs/max'; +import { Radio } from 'antd'; +import React from 'react'; +import { addWorkerGuide, containerInstallOptions } from '../config'; +import './styles/installation.less'; + +type ViewModalProps = { + token: string; +}; + +const AddWorker: React.FC = (props) => { + const intl = useIntl(); + + const origin = window.location.origin; + const [activeKey, setActiveKey] = React.useState('cuda'); + const versionInfo = getAtomStorage(GPUStackVersionAtom); + + const code = React.useMemo(() => { + let version = versionInfo?.version; + if (!version || !versionInfo.isProduction) { + version = 'main'; + } + if (activeKey === 'cuda') { + return addWorkerGuide.docker.registerWorker({ + server: origin, + tag: version, + token: props.token + }); + } + return addWorkerGuide.docker.registerWorker({ + server: origin, + tag: `${version}-${activeKey}`, + token: props.token + }); + }, [versionInfo, activeKey, props.token, origin]); + + return ( +
+
+ + 1.{' '} + + {intl.formatMessage({ id: 'resources.worker.container.supported' })} + + + + + 2.{' '} + {intl.formatMessage( + { id: 'resources.worker.current.version' }, + { version: versionInfo.version } + )} + + + 3. {intl.formatMessage({ id: 'resources.worker.select.command' })} + +
+
+ setActiveKey(e.target.value)} + size="small" + /> +
+ +

+ + {intl.formatMessage({ id: 'resources.worker.add.step3' })} +

+
+ ); +}; + +export default React.memo(AddWorker); diff --git a/src/pages/resources/components/script-install.tsx b/src/pages/resources/components/script-install.tsx new file mode 100644 index 00000000..2a59aa93 --- /dev/null +++ b/src/pages/resources/components/script-install.tsx @@ -0,0 +1,40 @@ +import HighlightCode from '@/components/highlight-code'; +import { BulbOutlined } from '@ant-design/icons'; +import { useIntl } from '@umijs/max'; +import React from 'react'; +import { addWorkerGuide } from '../config'; + +type ViewModalProps = { token: string }; + +const AddWorker: React.FC = (props) => { + const intl = useIntl(); + + const origin = window.location.origin; + + return ( +
+

{intl.formatMessage({ id: 'resources.worker.linuxormaxos' })}

+ +

Windows

+ +

+ + {intl.formatMessage({ id: 'resources.worker.add.step3' })} +

+
+ ); +}; + +export default React.memo(AddWorker); diff --git a/src/pages/resources/components/styles/installation.less b/src/pages/resources/components/styles/installation.less new file mode 100644 index 00000000..7cb2bae7 --- /dev/null +++ b/src/pages/resources/components/styles/installation.less @@ -0,0 +1,13 @@ +.container-install { + .notes { + padding: 10px 0; + display: flex; + flex-direction: column; + gap: 5px; + border-left: 2px solid var(--ant-color-split); + margin-bottom: 20px; + padding-left: 16px; + background: var(--color-fill-sider); + border-radius: 2px; + } +} diff --git a/src/pages/resources/config/index.ts b/src/pages/resources/config/index.ts index 844afa62..db900d78 100644 --- a/src/pages/resources/config/index.ts +++ b/src/pages/resources/config/index.ts @@ -18,22 +18,29 @@ export const status: any = { export const addWorkerGuide = { mac: { getToken: 'cat /var/lib/gpustack/token', - registerWorker(server: string) { - return `curl -sfL https://get.gpustack.ai | sh -s - --server-url ${server} --token mytoken`; + registerWorker(params: { server: string; token: string }) { + return `curl -sfL https://get.gpustack.ai | sh -s - --server-url ${params.server} --token ${params.token}`; } }, win: { getToken: 'Get-Content -Path (Join-Path -Path $env:APPDATA -ChildPath "gpustack\\token") -Raw', - registerWorker(server: string) { - return `Invoke-Expression "& { $((Invoke-WebRequest -Uri "https://get.gpustack.ai" -UseBasicParsing).Content) } --server-url ${server} --token mytoken"`; + registerWorker(params: { server: string; token: string }) { + return `Invoke-Expression "& { $((Invoke-WebRequest -Uri "https://get.gpustack.ai" -UseBasicParsing).Content) } --server-url ${params.server} --token ${params.token}"`; } }, docker: { getToken: 'Get-Content -Path (Join-Path -Path $env:APPDATA -ChildPath "gpustack\\token") -Raw', - registerWorker(server: string) { - return `docker run -d --gpus all --ipc=host --network=host gpustack/gpustack --server-url ${server} --token mytoken`; + registerWorker(params: { server: string; tag: string; token: string }) { + return `docker run -d --gpus all --ipc=host --network=host gpustack/gpustack:${params.tag} --server-url ${params.server} --token ${params.token}`; } } }; + +export const containerInstallOptions = [ + { label: 'CUDA', value: 'cuda' }, + { label: 'CANN', value: 'npu' }, + { label: 'MUSA', value: 'musa' }, + { label: 'CPU', value: 'cpu' } +];