fix: add worker token do not update
This commit is contained in:
@@ -11,6 +11,7 @@ interface ViewerProps {
|
||||
options?: Global.BaseOption<string>[];
|
||||
defaultValue?: string;
|
||||
headerHeight?: number;
|
||||
height?: number;
|
||||
lang?: string;
|
||||
onChange?: (value: string | number) => void;
|
||||
}
|
||||
@@ -31,6 +32,7 @@ const CommandViewer: React.FC<ViewerProps> = (props) => {
|
||||
defaultValue,
|
||||
options = [],
|
||||
headerHeight = 40,
|
||||
height = 380,
|
||||
lang,
|
||||
onChange
|
||||
} = props || {};
|
||||
@@ -66,7 +68,7 @@ const CommandViewer: React.FC<ViewerProps> = (props) => {
|
||||
}
|
||||
>
|
||||
<HighlightCode
|
||||
height={380}
|
||||
height={height}
|
||||
theme="dark"
|
||||
code={code}
|
||||
lang={lang || value}
|
||||
|
||||
@@ -36,6 +36,7 @@ import PoolRows from './components/pool-rows';
|
||||
import { ProviderType, ProviderValueMap } from './config';
|
||||
import {
|
||||
ClusterListItem,
|
||||
CredentialListItem,
|
||||
ClusterFormData as FormData,
|
||||
ClusterListItem as ListItem,
|
||||
NodePoolFormData
|
||||
@@ -231,7 +232,7 @@ const Clusters: React.FC = () => {
|
||||
useEffect(() => {
|
||||
const fetchCredentialList = async () => {
|
||||
const data = await queryCredentialList({ page: -1 });
|
||||
const list = data?.items?.map((item) => ({
|
||||
const list = data?.items?.map((item: CredentialListItem) => ({
|
||||
label: item.name,
|
||||
value: item.id
|
||||
}));
|
||||
|
||||
@@ -79,6 +79,9 @@ const AddWorker: React.FC<AddWorkerProps> = (props) => {
|
||||
if (open && cluster_id && firstLoad.current) {
|
||||
handleOnClusterChange(cluster_id);
|
||||
}
|
||||
return () => {
|
||||
firstLoad.current = true;
|
||||
};
|
||||
}, [open, cluster_id]);
|
||||
|
||||
return (
|
||||
|
||||
@@ -17,10 +17,11 @@ import { useIntl, useNavigate } from '@umijs/max';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { Button, Tag } from 'antd';
|
||||
import _ from 'lodash';
|
||||
import { useMemo } from 'react';
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import styled from 'styled-components';
|
||||
import { modelCategoriesMap } from '../config';
|
||||
import { ListItem } from '../config/types';
|
||||
import useGenericProxy from '../hooks/use-generic-proxy';
|
||||
|
||||
const GPUSTACK_API = GPUSTACK_API_BASE_URL;
|
||||
|
||||
@@ -75,7 +76,7 @@ const Tips = styled.div`
|
||||
gap: 8px;
|
||||
}
|
||||
dd {
|
||||
margin-bottom: 16px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
`;
|
||||
|
||||
@@ -98,21 +99,22 @@ interface ApiAccessInfoProps {
|
||||
const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
||||
const intl = useIntl();
|
||||
const navigate = useNavigate();
|
||||
const { GenericProxyCommandCode, openProxyModal } = useGenericProxy();
|
||||
|
||||
const getModelCategory = useMemoizedFn((categories: string[]) => {
|
||||
const getProxyEndPoint = useMemoizedFn((categories: string[]) => {
|
||||
for (const [category, config] of Object.entries(API_MAP)) {
|
||||
if (categories.includes(category)) {
|
||||
return `${MODEL_PROXY}${config.api}`;
|
||||
}
|
||||
}
|
||||
return `${MODEL_PROXY}${CHAT_API}`;
|
||||
return `${window.location.origin}${MODEL_PROXY}/<YOUR_API_PATH>`;
|
||||
});
|
||||
|
||||
const endPoint = useMemo(() => {
|
||||
if (!data.generic_proxy) {
|
||||
return `${window.location.origin}/${GPUSTACK_API}`;
|
||||
}
|
||||
return getModelCategory(data.categories || []);
|
||||
return getProxyEndPoint(data.categories || []);
|
||||
}, [data]);
|
||||
|
||||
const isRanker = useMemo(() => {
|
||||
@@ -123,6 +125,12 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (open && data.generic_proxy) {
|
||||
openProxyModal(data);
|
||||
}
|
||||
}, [open, data, openProxyModal]);
|
||||
|
||||
return (
|
||||
<ScrollerModal
|
||||
open={open}
|
||||
@@ -130,7 +138,7 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
||||
top: '20%'
|
||||
}}
|
||||
title={intl.formatMessage({ id: 'models.table.button.apiAccessInfo' })}
|
||||
width={550}
|
||||
width={600}
|
||||
destroyOnHidden
|
||||
closable={true}
|
||||
maskClosable={false}
|
||||
@@ -156,12 +164,17 @@ const ApiAccessInfo = ({ open, data, onClose }: ApiAccessInfoProps) => {
|
||||
></dd>
|
||||
</dl>
|
||||
</Tips>
|
||||
{data.generic_proxy && (
|
||||
<div style={{ paddingLeft: 20, marginBottom: 12 }}>
|
||||
{GenericProxyCommandCode}
|
||||
</div>
|
||||
)}
|
||||
<ApiAccessInfoWrapper>
|
||||
<span className="label">
|
||||
{intl.formatMessage({ id: 'models.table.apiAccessInfo.endpoint' })}
|
||||
</span>
|
||||
<span className="value">
|
||||
<AutoTooltip ghost maxWidth={data.generic_proxy ? 300 : 180}>
|
||||
<AutoTooltip ghost maxWidth={data.generic_proxy ? 400 : 180}>
|
||||
{endPoint}
|
||||
</AutoTooltip>
|
||||
{!data.generic_proxy && (
|
||||
|
||||
@@ -106,7 +106,7 @@ const KVCacheForm = () => {
|
||||
)}
|
||||
min={0}
|
||||
step={1}
|
||||
precision={1}
|
||||
precision={0}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item<FormData> name={['extended_kv_cache', 'chunk_size']}>
|
||||
|
||||
@@ -0,0 +1,149 @@
|
||||
import CommandViewer from '@/pages/_components/command-viewer';
|
||||
import {
|
||||
AUDIO_SPEECH_TO_TEXT_API,
|
||||
AUDIO_TEXT_TO_SPEECH_API,
|
||||
CHAT_API,
|
||||
CREAT_IMAGE_API,
|
||||
EMBEDDING_API,
|
||||
MODEL_PROXY,
|
||||
RERANKER_API
|
||||
} from '@/pages/playground/apis';
|
||||
import {
|
||||
generateSpeechToTextCurlCode,
|
||||
generateTextToSpeechCurlCode
|
||||
} from '@/pages/playground/view-code/audio';
|
||||
import { generateEmbeddingCurlCode } from '@/pages/playground/view-code/embedding';
|
||||
import { generateImageCurlCode } from '@/pages/playground/view-code/image';
|
||||
import { generateLLmCurlCode } from '@/pages/playground/view-code/llm';
|
||||
import { generateRerankCurlCode } from '@/pages/playground/view-code/rerank';
|
||||
import { useMemoizedFn } from 'ahooks';
|
||||
import { useState } from 'react';
|
||||
import { modelCategoriesMap } from '../config';
|
||||
|
||||
const API_MAP: Record<
|
||||
string,
|
||||
{ api: string; parameters: any; generateCurlCode: (args: any) => string }
|
||||
> = {
|
||||
[modelCategoriesMap.embedding]: {
|
||||
api: EMBEDDING_API,
|
||||
parameters: {
|
||||
query: 'What are the benefits of regular exercise?',
|
||||
documents: [
|
||||
'Regular physical activity helps improve cardiovascular health and mental well-being.',
|
||||
'Eating too much sugar can lead to health issues.',
|
||||
'Exercise is often done in gyms or outdoors.'
|
||||
]
|
||||
},
|
||||
generateCurlCode: generateEmbeddingCurlCode
|
||||
},
|
||||
[modelCategoriesMap.llm]: {
|
||||
api: CHAT_API,
|
||||
parameters: {
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: 'Hello, introduce yourself'
|
||||
}
|
||||
]
|
||||
},
|
||||
generateCurlCode: generateLLmCurlCode
|
||||
},
|
||||
[modelCategoriesMap.image]: {
|
||||
api: CREAT_IMAGE_API,
|
||||
parameters: {},
|
||||
generateCurlCode: generateImageCurlCode
|
||||
},
|
||||
[modelCategoriesMap.text_to_speech]: {
|
||||
api: AUDIO_TEXT_TO_SPEECH_API,
|
||||
parameters: {
|
||||
response_format: 'mp3',
|
||||
input: ''
|
||||
},
|
||||
generateCurlCode: generateTextToSpeechCurlCode
|
||||
},
|
||||
[modelCategoriesMap.speech_to_text]: {
|
||||
api: AUDIO_SPEECH_TO_TEXT_API,
|
||||
parameters: {},
|
||||
generateCurlCode: generateSpeechToTextCurlCode
|
||||
},
|
||||
[modelCategoriesMap.reranker]: {
|
||||
api: RERANKER_API,
|
||||
parameters: {
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: 'Hello, introduce yourself'
|
||||
}
|
||||
]
|
||||
},
|
||||
generateCurlCode: generateRerankCurlCode
|
||||
}
|
||||
};
|
||||
|
||||
const langOptions = [{ label: 'Curl', value: 'bash' }];
|
||||
|
||||
const useGenericProxy = () => {
|
||||
const [modalStatus, setModalStatus] = useState<{
|
||||
codeValue: string;
|
||||
}>({ codeValue: '' });
|
||||
|
||||
const getModelCategory = (categories: string[]) => {
|
||||
for (const [category, config] of Object.entries(API_MAP)) {
|
||||
if (categories.includes(category)) {
|
||||
return {
|
||||
category,
|
||||
api: `${MODEL_PROXY}${config.api}`,
|
||||
parameters: config.parameters,
|
||||
generateCurlCode: config.generateCurlCode
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
category: modelCategoriesMap.llm,
|
||||
api: CHAT_API,
|
||||
parameters: {
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: 'Hello, introduce yourself'
|
||||
}
|
||||
]
|
||||
},
|
||||
generateCurlCode: generateLLmCurlCode
|
||||
};
|
||||
};
|
||||
|
||||
const openProxyModal = useMemoizedFn((data?: any) => {
|
||||
const { api, generateCurlCode, parameters } = getModelCategory(
|
||||
data?.categories || []
|
||||
);
|
||||
|
||||
setModalStatus({
|
||||
codeValue: generateCurlCode({
|
||||
api,
|
||||
modelProxy: true,
|
||||
parameters: {
|
||||
model: data?.name || ''
|
||||
}
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
const GenericProxyCommandCode = (
|
||||
<CommandViewer
|
||||
code={modalStatus.codeValue}
|
||||
copyText={modalStatus.codeValue}
|
||||
options={langOptions}
|
||||
defaultValue={'bash'}
|
||||
height={200}
|
||||
></CommandViewer>
|
||||
);
|
||||
|
||||
return {
|
||||
GenericProxyCommandCode,
|
||||
openProxyModal,
|
||||
setModalStatus
|
||||
};
|
||||
};
|
||||
|
||||
export default useGenericProxy;
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { GPUSTACK_API, MODEL_PROXY, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
||||
|
||||
export const generateSpeechToTextCurlCode = ({
|
||||
@@ -9,7 +9,9 @@ export const generateSpeechToTextCurlCode = ({
|
||||
}: Record<string, any>) => {
|
||||
const host = window.location.origin;
|
||||
// replace url OPENAI_COMPATIBLE with GPUSTACK
|
||||
const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
const api = modelProxy
|
||||
? `${MODEL_PROXY}/\${YOUR_API_PATH}`
|
||||
: url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
|
||||
// ========================= Curl =========================
|
||||
const curlCode = `
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { GPUSTACK_API, MODEL_PROXY, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
||||
|
||||
export const generateEmbeddingCurlCode = ({
|
||||
@@ -7,7 +7,9 @@ export const generateEmbeddingCurlCode = ({
|
||||
parameters
|
||||
}: Record<string, any>) => {
|
||||
const host = window.location.origin;
|
||||
const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
const api = modelProxy
|
||||
? `${MODEL_PROXY}/\${YOUR_API_PATH}`
|
||||
: url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
|
||||
// ========================= Curl =========================
|
||||
const curlCode = `
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import _ from 'lodash';
|
||||
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { GPUSTACK_API, MODEL_PROXY, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
||||
|
||||
export const generateImageCurlCode = ({
|
||||
@@ -10,7 +10,9 @@ export const generateImageCurlCode = ({
|
||||
edit = false
|
||||
}: Record<string, any>) => {
|
||||
const host = window.location.origin;
|
||||
const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
const api = modelProxy
|
||||
? `${MODEL_PROXY}/\${YOUR_API_PATH}`
|
||||
: url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
|
||||
// ========================= Curl =========================
|
||||
let curlCode = `
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { GPUSTACK_API, MODEL_PROXY, OPENAI_COMPATIBLE } from '../apis';
|
||||
import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils';
|
||||
|
||||
export const generateLLmCurlCode = ({
|
||||
@@ -7,7 +7,9 @@ export const generateLLmCurlCode = ({
|
||||
parameters
|
||||
}: Record<string, any>) => {
|
||||
const host = window.location.origin;
|
||||
const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
const api = modelProxy
|
||||
? `${MODEL_PROXY}/\${YOUR_API_PATH}`
|
||||
: url.replace(OPENAI_COMPATIBLE, GPUSTACK_API);
|
||||
|
||||
// ========================= Curl =========================
|
||||
const curlCode = `
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { MODEL_PROXY } from '../apis';
|
||||
import { formatCurlArgs } from './utils';
|
||||
|
||||
export const generateRerankCurlCode = ({
|
||||
@@ -6,10 +7,11 @@ export const generateRerankCurlCode = ({
|
||||
parameters
|
||||
}: Record<string, any>) => {
|
||||
const host = window.location.origin;
|
||||
const apiUrl = modelProxy ? `${MODEL_PROXY}/\${YOUR_API_PATH}` : api;
|
||||
|
||||
// ========================= Curl =========================
|
||||
const curlCode = `
|
||||
curl ${host}${api} \\
|
||||
curl ${host}${apiUrl} \\
|
||||
-H "Content-Type: application/json" \\
|
||||
-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''}
|
||||
${formatCurlArgs(parameters, false)}`.trim();
|
||||
|
||||
Reference in New Issue
Block a user