diff --git a/config/proxy.ts b/config/proxy.ts index 1013d6a6..6beb12ac 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -19,6 +19,21 @@ export default function createProxyTable(target?: string) { secure: false, ws: true, pathRewrite: (pth: string) => pth.replace(`/^/${api}`, `/${api}`), + // onProxyRes: (proxyRes: any, req: any, res: any) => { + // proxyRes.on('data', (chunk: any) => { + // console.log('chunk=====', chunk); + // res.write(chunk); + // }); + + // proxyRes.on('end', () => { + // res.end(); + // }); + + // proxyRes.on('error', (err: any) => { + // console.error('Proxy stream error:', err); + // res.status(500).end('Stream error'); + // }); + // }, headers: { origin: newTarget, Connection: 'keep-alive' diff --git a/src/locales/en-US/models.ts b/src/locales/en-US/models.ts index 2137b0f3..f1e67510 100644 --- a/src/locales/en-US/models.ts +++ b/src/locales/en-US/models.ts @@ -71,7 +71,7 @@ export default { 'models.logs.pagination.next': 'Next {lines} Lines', 'models.form.localPath': 'Local Path', 'models.form.filePath': 'Model Path', - 'model.form.backendVersion': 'Backend Version', + 'models.form.backendVersion': 'Backend Version', 'models.form.backendVersion.tips': 'Pin a specific version to keep the backend stable across GPUStack upgrades.' }; diff --git a/src/locales/zh-CN/models.ts b/src/locales/zh-CN/models.ts index b4bceed5..4660c205 100644 --- a/src/locales/zh-CN/models.ts +++ b/src/locales/zh-CN/models.ts @@ -69,7 +69,7 @@ export default { 'models.logs.pagination.next': '下一 {lines} 行', 'models.form.localPath': '本地路径', 'models.form.filePath': '模型路径', - 'model.form.backendVersion': '后端版本', - 'model.form.backendVersion.tips': + 'models.form.backendVersion': '后端版本', + 'models.form.backendVersion.tips': '固定指定版本以保持后端在 GPUStack 升级过程中的稳定性' }; diff --git a/src/pages/llmodels/components/advance-config.tsx b/src/pages/llmodels/components/advance-config.tsx index 797c33b8..3777fd53 100644 --- a/src/pages/llmodels/components/advance-config.tsx +++ b/src/pages/llmodels/components/advance-config.tsx @@ -279,9 +279,9 @@ const AdvanceConfig: React.FC = (props) => { diff --git a/src/pages/llmodels/components/view-logs-modal.tsx b/src/pages/llmodels/components/view-logs-modal.tsx index 5aa21221..3309668d 100644 --- a/src/pages/llmodels/components/view-logs-modal.tsx +++ b/src/pages/llmodels/components/view-logs-modal.tsx @@ -34,7 +34,7 @@ const ViewCodeModal: React.FC = (props) => { }, [onCancel]); const updateHandler = (list: any) => { - const data = list?.find((item: any) => item.data.id === props.id); + const data = list?.find((item: any) => item.data?.id === props.id); if (data) { setEnableScorllLoad(!InstanceRealLogStatus.includes(data?.data?.state)); } @@ -45,7 +45,7 @@ const ViewCodeModal: React.FC = (props) => { if (open) { requestRef.current?.current?.cancel?.(); requestRef.current = setChunkRequest({ - url: `${MODELS_API}/${props.id}/instances`, + url: `${MODELS_API}/${props.modelId}/instances`, handler: updateHandler }); } diff --git a/src/pages/playground/apis/index.ts b/src/pages/playground/apis/index.ts index 3bff3a4f..5b0851e3 100644 --- a/src/pages/playground/apis/index.ts +++ b/src/pages/playground/apis/index.ts @@ -90,7 +90,7 @@ export const createImages = async ( export const textToSpeech = async (params: any, options?: any) => { const res = await fetch(AUDIO_TEXT_TO_SPEECH_API, { method: 'POST', - body: JSON.stringify(params), + body: JSON.stringify(params.data), signal: params.signal }); if (!res.ok) { @@ -102,7 +102,7 @@ export const textToSpeech = async (params: any, options?: any) => { export const speechToText = async (params: any, options?: any) => { const res = await fetch(AUDIO_SPEECH_TO_TEXT_API, { method: 'POST', - body: JSON.stringify(params), + body: JSON.stringify(params.data), signal: params.signal }); if (!res.ok) { diff --git a/src/pages/playground/components/ground-images.tsx b/src/pages/playground/components/ground-images.tsx index 0b38550a..ba6535d7 100644 --- a/src/pages/playground/components/ground-images.tsx +++ b/src/pages/playground/components/ground-images.tsx @@ -92,8 +92,11 @@ const GroundImages: React.FC = forwardRef((props, ref) => { dataUrl: string; height: number | string; width: string | number; + maxHeight: string | number; + maxWidth: string | number; uid: number; span?: number; + loading?: boolean; progress?: number; }[] >([ @@ -234,11 +237,12 @@ const GroundImages: React.FC = forwardRef((props, ref) => { .fill({}) .map((item, index: number) => { return { - dataUr: '', + dataUrl: 'data:image/png;base64,', ...size, progress: 0, - height: 'auto', - width: 'auto', + height: '100%', + width: '100%', + loading: true, uid: index }; }); @@ -249,32 +253,21 @@ const GroundImages: React.FC = forwardRef((props, ref) => { const params = { stream: true, + stream_options: { + chunk_result: true + }, prompt: current?.content || currentPrompt || '', ..._.omitBy(finalParameters, (value: string) => !value) }; const result: any = await fetchChunkedData({ data: params, - // url: 'http://192.168.1.3:40487/v1/images/generations', url: CREAT_IMAGE_API, - signal: requestToken.current.signal, - headers: { - 'Cache-Control': 'no-cache', - Accept: 'text/event-stream', - Connection: 'keep-alive' - } + signal: requestToken.current.signal }); - if (result?.error) { - setTokenResult({ - error: true, - errorMessage: - result?.data?.error?.message || result?.data?.message || '' - }); - return; - } - const { reader, decoder } = result; + const imgSize = _.split(finalParameters.size, 'x'); await readStreamData(reader, decoder, (chunk: any) => { if (chunk?.error) { @@ -284,23 +277,28 @@ const GroundImages: React.FC = forwardRef((props, ref) => { }); return; } - console.log('data:================', chunk); + chunk?.data?.forEach((item: any) => { const imgItem = newImageList[item.index]; + if (item.b64_json) { + imgItem.dataUrl += item.b64_json; + } newImageList[item.index] = { - dataUrl: `data:image/png;base64,${item.b64_json}`, + dataUrl: imgItem.dataUrl, height: '100%', width: '100%', + maxHeight: `${imgSize[1]}px`, + maxWidth: `${imgSize[0]}px`, uid: imgItem.uid, span: imgItem.span, + loading: _.round(item.progress, 0) < 100, progress: _.round(item.progress, 0) }; }); setImageList([...newImageList]); }); - console.log('result:', newImageList); } catch (error) { - console.log('error:', error); + // console.log('error:', error); requestToken.current?.abort?.(); setImageList([]); } finally { diff --git a/src/pages/playground/components/ground-stt.tsx b/src/pages/playground/components/ground-stt.tsx index 0c1b6e63..fc099aab 100644 --- a/src/pages/playground/components/ground-stt.tsx +++ b/src/pages/playground/components/ground-stt.tsx @@ -3,13 +3,11 @@ import AudioPlayer from '@/components/audio-player'; import IconFont from '@/components/icon-font'; import UploadAudio from '@/components/upload-audio'; import useOverlayScroller from '@/hooks/use-overlay-scroller'; -import { fetchChunkedData, readStreamData } from '@/utils/fetch-chunk-data'; import { readAudioFile } from '@/utils/load-audio-file'; import { AudioOutlined, ThunderboltOutlined } from '@ant-design/icons'; import { useIntl, useSearchParams } from '@umijs/max'; import { Button, Spin, Tag, Tooltip } from 'antd'; import classNames from 'classnames'; -import _ from 'lodash'; import 'overlayscrollbars/overlayscrollbars.css'; import { forwardRef, @@ -17,12 +15,10 @@ import { useCallback, useEffect, useImperativeHandle, - useMemo, useRef, useState } from 'react'; -import { CHAT_API } from '../apis'; -import { Roles, generateMessages } from '../config'; +import { CHAT_API, speechToText } from '../apis'; import { RealtimeParamsConfig as paramsConfig } from '../config/params-config'; import { MessageItem } from '../config/types'; import '../style/ground-left.less'; @@ -46,21 +42,24 @@ const initialValues = { const GroundLeft: React.FC = forwardRef((props, ref) => { const { modelList } = props; const messageId = useRef(0); - const [messageList, setMessageList] = useState([]); - + const [messageList, setMessageList] = useState([ + { + content: 'Generating text content...', + title: '', + role: '', + uid: messageId.current + } + ]); const intl = useIntl(); const [searchParams] = useSearchParams(); const selectModel = searchParams.get('model') || ''; const [parameters, setParams] = useState({}); - const [systemMessage, setSystemMessage] = useState(''); const [show, setShow] = useState(false); const [loading, setLoading] = useState(false); const [tokenResult, setTokenResult] = useState(null); const [collapse, setCollapse] = useState(false); - const contentRef = useRef(''); const controllerRef = useRef(null); const scroller = useRef(null); - const currentMessageRef = useRef(null); const paramsRef = useRef(null); const messageListLengthCache = useRef(0); const [audioPermissionOn, setAudioPermissionOn] = useState(true); @@ -87,37 +86,10 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { }; }); - const viewCodeMessage = useMemo(() => { - return generateMessages([ - { role: Roles.System, content: systemMessage }, - ...messageList - ]); - }, [messageList, systemMessage]); - const setMessageId = () => { messageId.current = messageId.current + 1; }; - const joinMessage = (chunk: any) => { - setTokenResult({ - ...(chunk?.usage ?? {}) - }); - - if (!chunk || !_.get(chunk, 'choices', []).length) { - return; - } - contentRef.current = - contentRef.current + _.get(chunk, 'choices.0.delta.content', ''); - setMessageList([ - ...messageList, - ...currentMessageRef.current, - { - role: Roles.Assistant, - content: contentRef.current, - uid: messageId.current - } - ]); - }; const handleStopConversation = () => { controllerRef.current?.abort?.(); setLoading(false); @@ -133,37 +105,15 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { controllerRef.current?.abort?.(); controllerRef.current = new AbortController(); const signal = controllerRef.current.signal; - currentMessageRef.current = current - ? [ - { - ...current, - uid: messageId.current - } - ] - : []; - - contentRef.current = ''; - setMessageList((pre) => { - return [...pre, ...currentMessageRef.current]; - }); - - const messageParams = [ - { role: Roles.System, content: systemMessage }, - ...messageList, - ...currentMessageRef.current - ]; - - const messages = generateMessages(messageParams); const chatParams = { - messages: messages, ...parameters, stream: true, stream_options: { include_usage: true } }; - const result: any = await fetchChunkedData({ + const result: any = await speechToText({ data: chatParams, url: CHAT_API, signal @@ -177,18 +127,14 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { }); return; } - setMessageId(); - const { reader, decoder } = result; - await readStreamData(reader, decoder, (chunk: any) => { - if (chunk?.error) { - setTokenResult({ - error: true, - errorMessage: chunk?.error?.message || chunk?.message || '' - }); - return; + setMessageList([ + { + content: 'Generating text content...', + title: '', + role: '', + uid: messageId.current } - joinMessage(chunk); - }); + ]); } catch (error) { // console.log('error:', error); } finally { @@ -204,41 +150,6 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { setTokenResult(null); }; - const renderTitle = useCallback((role: string) => { - return ( - - {intl.formatMessage({ id: `playground.${role}` })} - 00:10 - - ); - }, []); - - const handleSendMessage = (message: Omit) => { - setLoading(true); - setMessageList([ - ...messageList, - { - role: Roles.User, - title: renderTitle(Roles.User), - content: 'test data test data', - uid: messageId.current - } - ]); - - setTimeout(() => { - setMessageList([ - ...messageList, - { - role: Roles.Assistant, - title: renderTitle(Roles.Assistant), - content: 'generate by assistant', - uid: messageId.current - } - ]); - setLoading(false); - }, 1000); - }; - const handleCloseViewCode = () => { setShow(false); }; @@ -498,10 +409,9 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { {loading && ( @@ -543,10 +453,9 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { = forwardRef((props, ref) => { ...parameters, prompt: current?.content || currentPrompt }; - const result: any = await fetchChunkedData({ + const result: any = await textToSpeech({ data: chatParams, url: CHAT_API, signal @@ -265,6 +264,7 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { prompt: currentPrompt }} api="audio/speech" + clientType="audio.speech" parameters={parameters} onCancel={handleCloseViewCode} title={intl.formatMessage({ id: 'playground.viewcode' })} diff --git a/src/pages/playground/components/thumb-img.tsx b/src/pages/playground/components/thumb-img.tsx index 959450c8..1afcb9cf 100644 --- a/src/pages/playground/components/thumb-img.tsx +++ b/src/pages/playground/components/thumb-img.tsx @@ -47,7 +47,7 @@ const ThumbImg: React.FC<{ }} > <> - {loading ? ( + {item.loading ? ( ) : ( - + void ) => { const { done, value } = await reader.read(); - console.log('done====', done, value); if (done) { return; } let chunk = decoder.decode(value, { stream: true }); extractJSON(chunk).forEach((data) => { - console.log('data====', data); callback?.(data); }); - // callback(chunk); await readStreamData(reader, decoder, callback); };