diff --git a/src/components/segment-line/index.tsx b/src/components/segment-line/index.tsx index ad96f137..4c10e83c 100644 --- a/src/components/segment-line/index.tsx +++ b/src/components/segment-line/index.tsx @@ -83,6 +83,4 @@ const SegmentLine: React.FC = (props) => { ); }; -SegmentLine.displayName = 'SegmentLine'; - export default SegmentLine; diff --git a/src/config/settings.ts b/src/config/settings.ts index 7eaa8afe..d4ea6a4c 100644 --- a/src/config/settings.ts +++ b/src/config/settings.ts @@ -6,3 +6,5 @@ export const DEFAULT_ENTER_PAGE = { user: '/models/user-models', login: '/login' }; + +export const GPUSTACK_API_BASE_URL = 'v1'; diff --git a/src/locales/en-US/clusters.ts b/src/locales/en-US/clusters.ts index dc727c9b..41482430 100644 --- a/src/locales/en-US/clusters.ts +++ b/src/locales/en-US/clusters.ts @@ -41,7 +41,7 @@ export default { 'clusters.create.addworker.tips': ' Please make sure the prerequisites for {label} are met before executing the following command.', 'clusters.create.addCommand.tips': - ' On the Worker that needs to be added, run the following command to join it to the cluster.', + 'On the Worker that needs to be added, run the following command to join it to the cluster.', 'clusters.create.register.tips': ' On the Kubernetes cluster that needs to be added, run the following command to join its nodes to the cluster.', 'cluster.create.checkEnv.tips': diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index bddaa6f3..8d8c2a8b 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -246,7 +246,10 @@ export default { 'models.catalog.precision': 'Precision', 'models.form.gpuPerReplica.tips': 'Enter a custom number', 'models.form.generic_proxy': 'Enable Generic Proxy', - 'models.form.generic_proxy.tips': 'Enable Generic Proxy', + 'models.form.generic_proxy.tips': + 'After enabling the generic proxy, you can access URI paths that do not follow the OpenAI API standard.', 'models.form.generic_proxy.button': 'Generic Proxy', - 'models.accessControlModal.includeusers': 'Include Users' + 'models.accessControlModal.includeusers': 'Include Users', + 'models.table.genericProxy': + 'Refer to the curl example below. The proxy forwards requests with the /model/proxy prefix to the corresponding model. You need to specify the model name either in the X-GPUStack-Model request header or in the "model" property of the JSON body.' }; diff --git a/src/locales/ja-JP/clusters.ts b/src/locales/ja-JP/clusters.ts index 07cce657..e41d2e2a 100644 --- a/src/locales/ja-JP/clusters.ts +++ b/src/locales/ja-JP/clusters.ts @@ -41,7 +41,7 @@ export default { 'clusters.create.addworker.tips': ' Please make sure the prerequisites for {label} are met before executing the following command.', 'clusters.create.addCommand.tips': - ' On the Worker that needs to be added, run the following command to join it to the cluster.', + 'On the Worker that needs to be added, run the following command to join it to the cluster.', 'cluster.create.checkEnv.tips': 'Use the following command to check if the environment is ready', 'clusters.create.register.tips': @@ -101,7 +101,7 @@ export default { // 37. 'clusters.create.noRegions': 'No regions available', // 38. 'clusters.workerpool.batchSize.desc': 'Number of workers created simultaneously in the Worker pool', // 39. 'clusters.create.addworker.tips': ' Please make sure the prerequisites for {label} are met before executing the following command.', -// 40. 'clusters.create.addCommand.tips': ' On the Worker that needs to be added, run the following command to join it to the cluster.', +// 40. 'clusters.create.addCommand.tips': 'On the Worker that needs to be added, run the following command to join it to the cluster.', // 41. 'cluster.create.checkEnv.tips': 'Use the following command to check if the environment is ready', // 42. 'clusters.create.register.tips': ' On the Kubernetes cluster that needs to be added, run the following command to join its nodes to the cluster.', // 43. 'cluster.provider.comingsoon': 'Coming soon', diff --git a/src/locales/ja-JP/models.ts b/src/locales/ja-JP/models.ts index aab4e9a3..295683e9 100644 --- a/src/locales/ja-JP/models.ts +++ b/src/locales/ja-JP/models.ts @@ -246,9 +246,12 @@ export default { 'models.catalog.precision': 'Precision', 'models.form.gpuPerReplica.tips': 'Enter a custom number', 'models.form.generic_proxy': 'Enable Generic Proxy', - 'models.form.generic_proxy.tips': 'Enable Generic Proxy', + 'models.form.generic_proxy.tips': + 'After enabling the generic proxy, you can access URI paths that do not follow the OpenAI API standard.', 'models.form.generic_proxy.button': 'Generic Proxy', - 'models.accessControlModal.includeusers': 'Include Users' + 'models.accessControlModal.includeusers': 'Include Users', + 'models.table.genericProxy': + 'Refer to the curl example below. The proxy forwards requests with the /model/proxy prefix to the corresponding model. You need to specify the model name either in the X-GPUStack-Model request header or in the "model" property of the JSON body.' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== @@ -322,8 +325,9 @@ export default { // 51. 'models.catalog.precision': 'Precision', // 52. 'models.form.gpuPerReplica.tips': 'Enter a custom number', // 53. 'models.form.generic_proxy': 'Enable Generic Proxy', -// 54. 'models.form.generic_proxy.tips': 'Enable Generic Proxy', +// 54. 'models.form.generic_proxy.tips': 'After enabling the generic proxy, you can access URI paths that do not follow the OpenAI API standard.', // 55. 'models.form.generic_proxy.button': 'Generic Proxy', -// 56. 'models.accessControlModal.includeusers': 'Include Users' +// 56. 'models.accessControlModal.includeusers': 'Include Users', +// 57. 'models.table.genericProxy': 'Refer to the curl example below. The proxy forwards requests with the /model/proxy prefix to the corresponding model. You need to specify the model name either in the X-GPUStack-Model request header or in the "model" property of the JSON body.' // ========== End of To-Do List ========== diff --git a/src/locales/ru-RU/models.ts b/src/locales/ru-RU/models.ts index c03b017e..54dcdc66 100644 --- a/src/locales/ru-RU/models.ts +++ b/src/locales/ru-RU/models.ts @@ -249,9 +249,11 @@ export default { 'models.form.generic_proxy': 'Включить универсальный прокси', 'models.form.generic_proxy.tips': 'Включить универсальный прокси', 'models.form.generic_proxy.button': 'Универсальный прокси', - 'models.accessControlModal.includeusers': 'Включить пользователей' + 'models.accessControlModal.includeusers': 'Включить пользователей', + 'models.table.genericProxy': + 'Refer to the curl example below. The proxy forwards requests with the /model/proxy prefix to the corresponding model. You need to specify the model name either in the X-GPUStack-Model request header or in the "model" property of the JSON body.' }; // ========== To-Do: Translate Keys (Remove After Translation) ========== - +// 7. 'models.table.genericProxy': 'Refer to the curl example below. The proxy forwards requests with the /model/proxy prefix to the corresponding model. You need to specify the model name either in the X-GPUStack-Model request header or in the "model" property of the JSON body.' // ========== End of To-Do List ========== diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index b6dd7832..7d182e65 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -233,7 +233,10 @@ export default { 'models.catalog.precision': '精度', 'models.form.gpuPerReplica.tips': '输入自定义数值', 'models.form.generic_proxy': '启用通用代理', - 'models.form.generic_proxy.tips': '启用通用代理', + 'models.form.generic_proxy.tips': + '启用通用代理后可支持访问非 openai-API 标准的 URI 路径。', 'models.form.generic_proxy.button': '通用代理', - 'models.accessControlModal.includeusers': '显示用户' + 'models.accessControlModal.includeusers': '显示用户', + 'models.table.genericProxy': + '参考下面 curl 的方式,代理会将 /model/proxy 前缀的请求转发到对应的模型,需要在 X-GPUStack-Model 请求头或 JSON 请求体 "model" 属性设置模型名称。' }; diff --git a/src/pages/cluster-management/components/add-worker-step.tsx b/src/pages/cluster-management/components/add-worker-step.tsx index 2eb12a2f..7fa2b4e5 100644 --- a/src/pages/cluster-management/components/add-worker-step.tsx +++ b/src/pages/cluster-management/components/add-worker-step.tsx @@ -107,9 +107,6 @@ const AddWorkerStep: React.FC = ({ return ( - - {intl.formatMessage({ id: 'clusters.create.supportedGpu' })} - = ({ }); const modalRef = useRef(null); + const { GenericProxyModal, openProxyModal } = useGenericProxy(); + useEffect(() => { if (deleteIds?.length) { rowSelection.removeSelectedKey(deleteIds); @@ -456,6 +459,10 @@ const Models: React.FC = ({ handleViewAPIInfo(row); } + if (val === 'proxy') { + openProxyModal(row); + } + if (val === 'stop') { modalRef.current?.show({ content: 'models.instances', @@ -789,6 +796,7 @@ const Models: React.FC = ({ currentData={openAccessControlModal.currentData} action={openAccessControlModal.action} > + {GenericProxyModal} ); }; diff --git a/src/pages/llmodels/config/button-actions.ts b/src/pages/llmodels/config/button-actions.ts index 3e7b1502..7ecbfdfb 100644 --- a/src/pages/llmodels/config/button-actions.ts +++ b/src/pages/llmodels/config/button-actions.ts @@ -50,11 +50,11 @@ export const ActionList: ActionItem[] = [ key: 'chat', icon: icons.ExperimentOutlined }, - // { - // label: 'models.form.generic_proxy.button', - // key: 'proxy', - // icon: icons.CaptivePortal - // }, + { + label: 'models.form.generic_proxy.button', + key: 'proxy', + icon: icons.CaptivePortal + }, { label: 'models.table.button.apiAccessInfo', key: 'api', @@ -197,6 +197,7 @@ export const modelFileActions = [ export const categoryToPathMap: Record = { [modelCategoriesMap.llm]: '/playground/chat', + [modelCategoriesMap.image]: '/playground/text-to-image', [modelCategoriesMap.text_to_speech]: '/playground/speech?type=tts', [modelCategoriesMap.speech_to_text]: '/playground/speech?type=stt', [modelCategoriesMap.reranker]: '/playground/rerank', diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index e06542f5..5582d0e0 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -287,6 +287,7 @@ export const modelCategoriesMap = { export const categoryOptions = [ { label: 'LLM', value: modelCategoriesMap.llm }, + { label: 'Image', value: modelCategoriesMap.image }, { label: 'Embedding', value: modelCategoriesMap.embedding }, { label: 'Reranker', value: modelCategoriesMap.reranker }, { label: 'Text-to-Speech', value: modelCategoriesMap.text_to_speech }, diff --git a/src/pages/llmodels/forms/advance-config.tsx b/src/pages/llmodels/forms/advance-config.tsx index 2e45304d..56efb885 100644 --- a/src/pages/llmodels/forms/advance-config.tsx +++ b/src/pages/llmodels/forms/advance-config.tsx @@ -133,7 +133,7 @@ const AdvanceConfig = () => { })} > - {/* + name="generic_proxy" valuePropName="checked" style={{ marginBottom: 8 }} @@ -146,7 +146,7 @@ const AdvanceConfig = () => { id: 'models.form.generic_proxy' })} > - */} + ); }; diff --git a/src/pages/llmodels/hooks/use-generic-proxy.tsx b/src/pages/llmodels/hooks/use-generic-proxy.tsx index 77f08645..b7e85e33 100644 --- a/src/pages/llmodels/hooks/use-generic-proxy.tsx +++ b/src/pages/llmodels/hooks/use-generic-proxy.tsx @@ -1,15 +1,62 @@ import ScrollerModal from '@/components/scroller-modal'; import CommandViewer from '@/pages/_components/command-viewer'; -import { GPUSTACK_API, OPENAI_COMPATIBLE } from '@/pages/playground/apis'; +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 { formatCurlArgs } from '@/pages/playground/view-code/utils'; import { useIntl } from '@umijs/max'; import { useState } from 'react'; +import { modelCategoriesMap } from '../config'; + +const API_MAP: Record< + string, + { api: string; generateCurlCode: (args: any) => string } +> = { + [modelCategoriesMap.embedding]: { + api: EMBEDDING_API, + generateCurlCode: generateEmbeddingCurlCode + }, + [modelCategoriesMap.llm]: { + api: CHAT_API, + generateCurlCode: generateLLmCurlCode + }, + [modelCategoriesMap.image]: { + api: CREAT_IMAGE_API, + generateCurlCode: generateImageCurlCode + }, + [modelCategoriesMap.text_to_speech]: { + api: AUDIO_TEXT_TO_SPEECH_API, + generateCurlCode: generateTextToSpeechCurlCode + }, + [modelCategoriesMap.speech_to_text]: { + api: AUDIO_SPEECH_TO_TEXT_API, + generateCurlCode: generateSpeechToTextCurlCode + }, + [modelCategoriesMap.reranker]: { + api: RERANKER_API, + generateCurlCode: generateRerankCurlCode + } +}; const langOptions = [{ label: 'Curl', value: 'bash' }]; const generateCode = ({ api: url, parameters }: Record) => { const host = window.location.origin; - const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + const api = '/model/proxy/v1/'; // ========================= Curl ========================= const curlCode = ` @@ -17,6 +64,8 @@ curl ${host}${api} \\ -H "Content-Type: application/json" \\ -H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ ${formatCurlArgs(parameters, false)}`.trim(); + + return curlCode; }; const useGenericProxy = () => { @@ -33,38 +82,67 @@ const useGenericProxy = () => { }); }; + const getModelCategory = (categories: string[]) => { + for (const [category, config] of Object.entries(API_MAP)) { + if (categories.includes(category)) { + return { + category, + api: `${MODEL_PROXY}${config.api}`, + generateCurlCode: config.generateCurlCode + }; + } + } + return { + category: modelCategoriesMap.llm, + api: CHAT_API, + generateCurlCode: generateLLmCurlCode + }; + }; + const openProxyModal = (data?: any) => { + const { api, generateCurlCode } = getModelCategory(data?.categories || []); + setModalStatus({ open: true, - codeValue: data?.generic_proxy_command || '' + codeValue: generateCurlCode({ + api, + modelProxy: true, + parameters: { + model: data?.name || '' + } + }) }); }; - const GenericProxyModal = () => { - return ( - - - - ); - }; + const GenericProxyModal = ( + +
+ +
+ ); return { GenericProxyModal, diff --git a/src/pages/playground/apis/index.ts b/src/pages/playground/apis/index.ts index e51e966a..4206db87 100644 --- a/src/pages/playground/apis/index.ts +++ b/src/pages/playground/apis/index.ts @@ -1,8 +1,9 @@ +import { GPUSTACK_API_BASE_URL } from '@/config/settings'; import { request } from '@umijs/max'; export const OPENAI_COMPATIBLE = 'v1-openai'; -export const GPUSTACK_API = 'v1'; +export const GPUSTACK_API = GPUSTACK_API_BASE_URL; export const CHAT_API = `/${OPENAI_COMPATIBLE}/chat/completions`; @@ -19,6 +20,8 @@ export const AUDIO_TEXT_TO_SPEECH_API = `/${OPENAI_COMPATIBLE}/audio/speech`; export const AUDIO_SPEECH_TO_TEXT_API = `/${OPENAI_COMPATIBLE}/audio/transcriptions`; +export const MODEL_PROXY = '/model/proxy'; + export async function execChatCompletions(params: any) { return request(`${CHAT_API}`, { method: 'POST', diff --git a/src/pages/playground/components/view-common-code.tsx b/src/pages/playground/components/view-common-code.tsx index 17019b4c..96b66c21 100644 --- a/src/pages/playground/components/view-common-code.tsx +++ b/src/pages/playground/components/view-common-code.tsx @@ -69,7 +69,7 @@ const ViewCodeModal: React.FC = (props) => { width={600} footer={null} > -
+
{intl.formatMessage({ id: 'playground.viewcode.info' })}
@@ -81,7 +81,7 @@ const ViewCodeModal: React.FC = (props) => { onChange={handleOnChangeLang} >
diff --git a/src/pages/playground/view-code/audio.ts b/src/pages/playground/view-code/audio.ts index b315d123..dcf3a13c 100644 --- a/src/pages/playground/view-code/audio.ts +++ b/src/pages/playground/view-code/audio.ts @@ -1,8 +1,9 @@ import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis'; import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils'; -export const speechToTextCode = ({ +export const generateSpeechToTextCurlCode = ({ api: url, + modelProxy, parameters }: Record) => { const host = window.location.origin; @@ -13,12 +14,26 @@ export const speechToTextCode = ({ const curlCode = ` curl ${host}${api} \\ -H "Content-Type: multipart/form-data" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} -F file="@/path/to/file/audio.mp3;type=audio/mpeg" \\ ${formatCurlArgs(parameters, true)}` .trim() .replace(/\\$/g, ''); + return curlCode; +}; + +export const speechToTextCode = ({ + api: url, + parameters +}: Record) => { + const host = window.location.origin; + // replace url OPENAI_COMPATIBLE with GPUSTACK + const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + + // ========================= Curl ========================= + const curlCode = generateSpeechToTextCurlCode({ api: url, parameters }); + // ========================= Python ========================= const pythonCode = ` from openai import OpenAI\n @@ -67,8 +82,9 @@ main();`.trim(); }; }; -export const TextToSpeechCode = ({ +export const generateTextToSpeechCurlCode = ({ api: url, + modelProxy, parameters }: Record) => { const host = window.location.origin; @@ -78,9 +94,22 @@ export const TextToSpeechCode = ({ const curlCode = ` curl ${host}${api} \\ -H "Content-Type: application/json" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} ${formatCurlArgs(parameters, false)} \\\n--output output.${parameters.response_format}`.trim(); + return curlCode; +}; + +export const TextToSpeechCode = ({ + api: url, + parameters +}: Record) => { + const host = window.location.origin; + const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + + // ========================= Curl ========================= + const curlCode = generateTextToSpeechCurlCode({ api: url, parameters }); + // ========================= Python ========================= const pythonCode = ` from pathlib import Path diff --git a/src/pages/playground/view-code/embedding.ts b/src/pages/playground/view-code/embedding.ts index 450dc88d..7b02788d 100644 --- a/src/pages/playground/view-code/embedding.ts +++ b/src/pages/playground/view-code/embedding.ts @@ -1,8 +1,9 @@ import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis'; import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils'; -export const generateEmbeddingCode = ({ +export const generateEmbeddingCurlCode = ({ api: url, + modelProxy, parameters }: Record) => { const host = window.location.origin; @@ -12,9 +13,22 @@ export const generateEmbeddingCode = ({ const curlCode = ` curl ${host}${api} \\ -H "Content-Type: application/json" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} ${formatCurlArgs(parameters, false)}`.trim(); + return curlCode; +}; + +export const generateEmbeddingCode = ({ + api: url, + parameters +}: Record) => { + const host = window.location.origin; + const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + + // ========================= Curl ========================= + const curlCode = generateEmbeddingCurlCode({ api: url, parameters }); + // ========================= Python ========================= const pythonCode = ` from openai import OpenAI\n diff --git a/src/pages/playground/view-code/image.ts b/src/pages/playground/view-code/image.ts index 3f8554fb..3010e940 100644 --- a/src/pages/playground/view-code/image.ts +++ b/src/pages/playground/view-code/image.ts @@ -2,6 +2,38 @@ import _ from 'lodash'; import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis'; import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils'; +export const generateImageCurlCode = ({ + api: url, + parameters, + modelProxy, + isFormdata = false, + edit = false +}: Record) => { + const host = window.location.origin; + const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + + // ========================= Curl ========================= + let curlCode = ` +curl ${host}${api} \\ +-H "Content-Type: application/json" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} +${formatCurlArgs(parameters, isFormdata)}`.trim(); + + if (edit) { + curlCode = ` +curl ${host}${api} \\ +-H "Content-Type: multipart/form-data" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} +-F image="@image.png" \\ +-F mask="@mask.png" \\ +${formatCurlArgs(_.omit(parameters, ['mask', 'image']), isFormdata)}` + .trim() + .replace(/\\$/, ''); + } + + return curlCode; +}; + export const generateImageCode = ({ api: url, parameters, @@ -12,23 +44,12 @@ export const generateImageCode = ({ const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); // ========================= Curl ========================= - let curlCode = ` -curl ${host}${api} \\ --H "Content-Type: application/json" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ -${formatCurlArgs(parameters, isFormdata)}`.trim(); - - if (edit) { - curlCode = ` -curl ${host}${api} \\ --H "Content-Type: multipart/form-data" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ --F image="@image.png" \\ --F mask="@mask.png" \\ -${formatCurlArgs(_.omit(parameters, ['mask', 'image']), isFormdata)}` - .trim() - .replace(/\\$/, ''); - } + let curlCode = generateImageCurlCode({ + api: url, + parameters, + isFormdata, + edit + }); // ========================= Python ========================= const pythonCode = ` diff --git a/src/pages/playground/view-code/llm.ts b/src/pages/playground/view-code/llm.ts index c531f22c..fd35bb02 100644 --- a/src/pages/playground/view-code/llm.ts +++ b/src/pages/playground/view-code/llm.ts @@ -1,8 +1,9 @@ import { GPUSTACK_API, OPENAI_COMPATIBLE } from '../apis'; import { fomatNodeJsParams, formatCurlArgs, formatPyParams } from './utils'; -export const generateLLMCode = ({ +export const generateLLmCurlCode = ({ api: url, + modelProxy, parameters }: Record) => { const host = window.location.origin; @@ -12,9 +13,22 @@ export const generateLLMCode = ({ const curlCode = ` curl ${host}${api} \\ -H "Content-Type: application/json" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} ${formatCurlArgs(parameters, false)}`.trim(); + return curlCode; +}; + +export const generateLLMCode = ({ + api: url, + parameters +}: Record) => { + const host = window.location.origin; + const api = url.replace(OPENAI_COMPATIBLE, GPUSTACK_API); + + // ========================= Curl ========================= + const curlCode = generateLLmCurlCode({ api: url, parameters }); + // ========================= Python ========================= const pythonCode = ` from openai import OpenAI\n diff --git a/src/pages/playground/view-code/rerank.ts b/src/pages/playground/view-code/rerank.ts index 58bc602d..92a8e7cf 100644 --- a/src/pages/playground/view-code/rerank.ts +++ b/src/pages/playground/view-code/rerank.ts @@ -1,7 +1,8 @@ import { formatCurlArgs } from './utils'; -export const generateRerankCode = ({ +export const generateRerankCurlCode = ({ api, + modelProxy, parameters }: Record) => { const host = window.location.origin; @@ -10,9 +11,21 @@ export const generateRerankCode = ({ const curlCode = ` curl ${host}${api} \\ -H "Content-Type: application/json" \\ --H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\ +-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\${modelProxy ? `\n-H "X-GPUStack-Model: ${parameters.model}" \\` : ''} ${formatCurlArgs(parameters, false)}`.trim(); + return curlCode; +}; + +export const generateRerankCode = ({ + api, + parameters +}: Record) => { + const host = window.location.origin; + + // ========================= Curl ========================= + const curlCode = generateRerankCurlCode({ api, parameters }); + // ========================= Python ========================= const pythonCode = ` import requests\n