fix: model be cleared when apply config to all in compare

This commit is contained in:
jialin
2024-11-22 18:25:07 +08:00
parent c8c22b3f22
commit a6f0f554f0
14 changed files with 124 additions and 102 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ const options: any = {
...grid, ...grid,
right: -1, right: -1,
top: -1, top: -1,
bottom: -1, bottom: 2,
left: -1, left: 2,
containLabel: true, containLabel: true,
borderRadius: 4 borderRadius: 4
}, },
@@ -13,7 +13,7 @@ interface LogsPaginationProps {
} }
const LogsPagination: React.FC<LogsPaginationProps> = (props) => { const LogsPagination: React.FC<LogsPaginationProps> = (props) => {
const { page, total, pageSize, onWheel, onNext, onPrev } = props; const { page, total, pageSize, onNext, onPrev } = props;
const intl = useIntl(); const intl = useIntl();
const handleOnPrev = () => { const handleOnPrev = () => {
@@ -24,10 +24,11 @@ interface LogsViewerProps {
params?: object; params?: object;
ref?: any; ref?: any;
tail?: number; tail?: number;
enableScorllLoad?: boolean;
diffHeight?: number; diffHeight?: number;
} }
const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => { const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => {
const { diffHeight, url, tail: defaultTail } = props; const { diffHeight, url, tail: defaultTail, enableScorllLoad = true } = props;
const { pageSize, page, setPage, setTotalPage, totalPage } = const { pageSize, page, setPage, setTotalPage, totalPage } =
useLogsPagination(); useLogsPagination();
const { setChunkFetch } = useSetChunkFetch(); const { setChunkFetch } = useSetChunkFetch();
@@ -169,7 +170,7 @@ const LogsViewer: React.FC<LogsViewerProps> = forwardRef((props, ref) => {
const handleOnScroll = useCallback( const handleOnScroll = useCallback(
async (isTop: boolean) => { async (isTop: boolean) => {
setIsAtTop(isTop); setIsAtTop(isTop);
if (loading || isLoadend || logs.length < pageSize) { if (loading || isLoadend || logs.length < pageSize || !enableScorllLoad) {
return; return;
} }
if (isTop && !isLoadend) { if (isTop && !isLoadend) {
-2
View File
@@ -199,14 +199,12 @@ const MarkdownViewer: React.FC<MarkdownViewerProps> = ({
return ( return (
<> <>
(
<div <div
style={{ height }} style={{ height }}
className="markdown-viewer custom-scrollbar-horizontal" className="markdown-viewer custom-scrollbar-horizontal"
> >
{renderTokens(tokens)} {renderTokens(tokens)}
</div> </div>
)
</> </>
); );
}; };
+39
View File
@@ -0,0 +1,39 @@
import { Component } from 'react';
interface ErrorBoundaryState {
hasError: boolean;
}
class ErrorBoundary extends Component<
{ children?: React.ReactNode },
ErrorBoundaryState
> {
constructor(props: any) {
super(props);
this.state = {
hasError: false
};
}
// 捕获错误并更新状态
static getDerivedStateFromError(error: any) {
console.error('Error caught by Error Boundary:', error);
return { hasError: true };
}
// 记录错误信息(可选)
componentDidCatch(error: any, info: any) {
console.error('Error caught by Error Boundary:', error);
console.error(info);
}
render() {
if (this.state.hasError) {
return <h1>Something went wrong.</h1>;
}
return this.props.children;
}
}
export default ErrorBoundary;
+10 -12
View File
@@ -205,9 +205,15 @@ const ModelCard: React.FC<{
if (!imgSrc) { if (!imgSrc) {
return ''; return '';
} }
return `https://modelscope.cn/api/v1/models/${modelData?.name}/repo?Revision=${modelData?.Revision}&View=true&FilePath=${imgSrc}`; if (modelSource === modelSourceMap.modelscope_value) {
return `https://modelscope.cn/api/v1/models/${modelData?.name}/repo?Revision=${modelData?.Revision}&View=true&FilePath=${imgSrc}`;
}
if (modelSource === modelSourceMap.huggingface_value) {
return `https://huggingface.co/${modelData?.id}/resolve/main/${imgSrc}`;
}
return '';
}, },
[modelData] [modelData, modelSource]
); );
useEffect(() => { useEffect(() => {
@@ -277,11 +283,7 @@ const ModelCard: React.FC<{
}} }}
> >
<MarkdownViewer <MarkdownViewer
generateImgLink={ generateImgLink={generateModeScopeImgLink}
modelSource === modelSourceMap.modelscope_value
? generateModeScopeImgLink
: undefined
}
content={readmeText} content={readmeText}
theme="light" theme="light"
></MarkdownViewer> ></MarkdownViewer>
@@ -310,11 +312,7 @@ const ModelCard: React.FC<{
</TitleWrapper> </TitleWrapper>
<div className="card-wrapper"> <div className="card-wrapper">
<MarkdownViewer <MarkdownViewer
generateImgLink={ generateImgLink={generateModeScopeImgLink}
modelSource === modelSourceMap.modelscope_value
? generateModeScopeImgLink
: undefined
}
content={readmeText} content={readmeText}
theme="light" theme="light"
></MarkdownViewer> ></MarkdownViewer>
+7 -35
View File
@@ -11,7 +11,6 @@ import HotKeys from '@/config/hotkeys';
import useExpandedRowKeys from '@/hooks/use-expanded-row-keys'; import useExpandedRowKeys from '@/hooks/use-expanded-row-keys';
import useTableRowSelection from '@/hooks/use-table-row-selection'; import useTableRowSelection from '@/hooks/use-table-row-selection';
import useTableSort from '@/hooks/use-table-sort'; import useTableSort from '@/hooks/use-table-sort';
import ViewCodeModal from '@/pages/playground/components/view-code-modal';
import { import {
GPUDeviceItem, GPUDeviceItem,
ListItem as WorkerListItem ListItem as WorkerListItem
@@ -88,10 +87,6 @@ const Models: React.FC<ModelsProps> = ({
const { sortOrder, setSortOrder } = useTableSort({ const { sortOrder, setSortOrder } = useTableSort({
defaultSortOrder: 'descend' defaultSortOrder: 'descend'
}); });
const [embeddingParams, setEmbeddingParams] = useState<any>({
params: {},
show: false
});
const [openLogModal, setOpenLogModal] = useState(false); const [openLogModal, setOpenLogModal] = useState(false);
const [openAddModal, setOpenAddModal] = useState(false); const [openAddModal, setOpenAddModal] = useState(false);
@@ -104,6 +99,8 @@ const Models: React.FC<ModelsProps> = ({
const [currentInstance, setCurrentInstance] = useState<{ const [currentInstance, setCurrentInstance] = useState<{
url: string; url: string;
status: string; status: string;
id?: number | string;
modelId?: number | string;
tail?: number; tail?: number;
}>({ }>({
url: '', url: '',
@@ -226,11 +223,6 @@ const Models: React.FC<ModelsProps> = ({
key: 'chat', key: 'chat',
icon: <WechatWorkOutlined /> icon: <WechatWorkOutlined />
}, },
// {
// label: 'common.button.viewcode',
// key: 'embedding',
// icon: <IconFont type="icon-code" />
// },
{ {
label: 'common.button.delete', label: 'common.button.delete',
key: 'delete', key: 'delete',
@@ -363,6 +355,8 @@ const Models: React.FC<ModelsProps> = ({
setCurrentInstance({ setCurrentInstance({
url: `${MODEL_INSTANCE_API}/${row.id}/logs`, url: `${MODEL_INSTANCE_API}/${row.id}/logs`,
status: row.state, status: row.state,
id: row.id,
modelId: row.model_id,
tail: row.state === InstanceStatusMap.Downloading ? undefined : PageSize tail: row.state === InstanceStatusMap.Downloading ? undefined : PageSize
}); });
setOpenLogModal(true); setOpenLogModal(true);
@@ -413,17 +407,8 @@ const Models: React.FC<ModelsProps> = ({
if (val === 'delete') { if (val === 'delete') {
handleDelete(row); handleDelete(row);
} }
if (val === 'embedding') {
setEmbeddingParams({
params: {
input: 'Your text string goes here',
model: row.name
},
show: true
});
}
}, },
[handleEdit, handleOpenPlayGround, handleDelete, setEmbeddingParams] [handleEdit, handleOpenPlayGround, handleDelete]
); );
const handleChildSelect = useCallback( const handleChildSelect = useCallback(
@@ -469,13 +454,6 @@ const Models: React.FC<ModelsProps> = ({
return ''; return '';
}, []); }, []);
const handleCloseViewCode = useCallback(() => {
setEmbeddingParams({
params: {},
show: false
});
}, []);
return ( return (
<> <>
<PageContainer <PageContainer
@@ -682,18 +660,12 @@ const Models: React.FC<ModelsProps> = ({
<ViewLogsModal <ViewLogsModal
url={currentInstance.url} url={currentInstance.url}
tail={currentInstance.tail} tail={currentInstance.tail}
id={currentInstance.id}
modelId={currentInstance.modelId}
open={openLogModal} open={openLogModal}
onCancel={handleLogModalCancel} onCancel={handleLogModalCancel}
></ViewLogsModal> ></ViewLogsModal>
<DeleteModal ref={modalRef}></DeleteModal> <DeleteModal ref={modalRef}></DeleteModal>
<ViewCodeModal
apiType="embedding"
open={embeddingParams.show}
messageList={[]}
parameters={embeddingParams.params}
onCancel={handleCloseViewCode}
title={intl.formatMessage({ id: 'playground.viewcode' })}
></ViewCodeModal>
</> </>
); );
}; };
@@ -1,52 +1,58 @@
import LogsViewer from '@/components/logs-viewer/virtual-log-list'; import LogsViewer from '@/components/logs-viewer/virtual-log-list';
import useSetChunkRequest from '@/hooks/use-chunk-request';
import { useIntl } from '@umijs/max'; import { useIntl } from '@umijs/max';
import { Modal } from 'antd'; import { Modal } from 'antd';
import React, { useCallback, useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { MODELS_API } from '../apis';
import { InstanceStatusMap } from '../config';
type ViewModalProps = { type ViewModalProps = {
open: boolean; open: boolean;
url: string; url: string;
id?: number | string;
modelId?: number | string;
tail?: number; tail?: number;
autoScroll?: boolean;
onCancel: () => void; onCancel: () => void;
}; };
const ViewCodeModal: React.FC<ViewModalProps> = (props) => { const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
const { open, url, onCancel, tail } = props || {};
const [modalSize, setModalSize] = useState<any>({
width: 600,
height: 420
});
const isFullScreenRef = React.useRef(false);
const logsViewerRef = React.useRef<any>(null);
const intl = useIntl();
const viewportHeight = window.innerHeight; const viewportHeight = window.innerHeight;
const viewHeight = viewportHeight - 86; const intl = useIntl();
const { setChunkRequest } = useSetChunkRequest();
const handleFullscreenToggle = useCallback(() => { const { open, url, onCancel, tail } = props || {};
isFullScreenRef.current = !isFullScreenRef.current; const [modalSize] = useState<any>({
setModalSize((size: any) => { width: '100%',
return { height: viewportHeight - 86
width: size.width === 600 ? '100%' : 600, });
height: size.height === 420 ? viewHeight : 420 const [enableScorllLoad, setEnableScorllLoad] = useState(true);
}; const logsViewerRef = React.useRef<any>(null);
}); const requestRef = React.useRef<any>(null);
}, []);
const handleCancel = useCallback(() => { const handleCancel = useCallback(() => {
logsViewerRef.current?.abort(); logsViewerRef.current?.abort();
onCancel(); onCancel();
}, [onCancel]); }, [onCancel]);
const updateHandler = (list: any) => {
const data = list?.find((item: any) => item.data.id === props.id);
if (data) {
setEnableScorllLoad(InstanceStatusMap.Downloading !== data?.data?.state);
}
};
useEffect(() => { useEffect(() => {
if (!props.id) return;
if (open) { if (open) {
isFullScreenRef.current = false; requestRef.current?.current?.cancel?.();
setModalSize({ requestRef.current = setChunkRequest({
width: '100%', url: `${MODELS_API}/${props.id}/instances`,
height: viewHeight handler: updateHandler
}); });
} }
}, [open]); return () => {
requestRef.current?.current?.cancel?.();
};
}, [props.id, open]);
return ( return (
<Modal <Modal
@@ -79,6 +85,7 @@ const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
diffHeight={93} diffHeight={93}
url={url} url={url}
tail={tail} tail={tail}
enableScorllLoad={enableScorllLoad}
params={{ params={{
follow: true follow: true
}} }}
+1
View File
@@ -130,6 +130,7 @@ const Models: React.FC = () => {
}; };
const updateInstanceHandler = (list: any) => { const updateInstanceHandler = (list: any) => {
console.log('updateInstanceHandler=====', list);
setModelInstances(list); setModelInstances(list);
}; };
@@ -221,7 +221,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
setLoading(false); setLoading(false);
}; };
const submitMessage = async (current?: { role: string; content: string }) => { const submitMessage = async (current?: { content: string }) => {
try { try {
await form.current?.form?.validateFields(); await form.current?.form?.validateFields();
if (!parameters.model) return; if (!parameters.model) return;
@@ -255,10 +255,13 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
const result: any = await fetchChunkedData({ const result: any = await fetchChunkedData({
data: params, data: params,
// url: 'http://192.168.50.27:40639/v1/images/generations',
url: CREAT_IMAGE_API, url: CREAT_IMAGE_API,
signal: requestToken.current.signal, signal: requestToken.current.signal,
headers: { headers: {
accept: 'text/event-stream' 'Cache-Control': 'no-cache',
Accept: 'text/event-stream',
Connection: 'keep-alive'
} }
}); });
@@ -281,8 +284,8 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
}); });
return; return;
} }
const data = chunk?.data || []; console.log('data:================', chunk);
data.forEach((item: any) => { chunk?.data?.forEach((item: any) => {
const imgItem = newImageList[item.index]; const imgItem = newImageList[item.index];
newImageList[item.index] = { newImageList[item.index] = {
dataUrl: `data:image/png;base64,${item.b64_json}`, dataUrl: `data:image/png;base64,${item.b64_json}`,
@@ -363,7 +366,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
> >
<SealInput.Number <SealInput.Number
style={{ width: '100%' }} style={{ width: '100%' }}
label={intl.formatMessage({ id: 'playground.params.width' })} label={`${intl.formatMessage({ id: 'playground.params.width' })}(px)`}
></SealInput.Number> ></SealInput.Number>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@@ -385,7 +388,7 @@ const GroundImages: React.FC<MessageProps> = forwardRef((props, ref) => {
> >
<SealInput.Number <SealInput.Number
style={{ width: '100%' }} style={{ width: '100%' }}
label="Height" label={`${intl.formatMessage({ id: 'playground.params.height' })}(px)`}
></SealInput.Number> ></SealInput.Number>
</Form.Item> </Form.Item>
</div> </div>
@@ -44,7 +44,6 @@ interface ModelItemProps {
const ModelItem: React.FC<ModelItemProps> = forwardRef( const ModelItem: React.FC<ModelItemProps> = forwardRef(
({ model, modelList, instanceId }, ref) => { ({ model, modelList, instanceId }, ref) => {
const { const {
spans,
globalParams, globalParams,
setGlobalParams, setGlobalParams,
setLoadingStatus, setLoadingStatus,
@@ -56,7 +55,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
const intl = useIntl(); const intl = useIntl();
const isApplyToAllModels = useRef(false); const isApplyToAllModels = useRef(false);
const [systemMessage, setSystemMessage] = useState<string>(''); const [systemMessage, setSystemMessage] = useState<string>('');
const [params, setParams] = useState<Record<string, any>>({}); const [params, setParams] = useState<Record<string, any>>({
model: model
});
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const messageId = useRef<number>(0); const messageId = useRef<number>(0);
const [messageList, setMessageList] = useState<MessageItem[]>([]); const [messageList, setMessageList] = useState<MessageItem[]>([]);
@@ -314,10 +315,9 @@ const ModelItem: React.FC<ModelItemProps> = forwardRef(
useEffect(() => { useEffect(() => {
setParams({ setParams({
...params, ...params,
model: model,
...globalParams ...globalParams
}); });
}, [globalParams, model]); }, [globalParams]);
useEffect(() => { useEffect(() => {
return () => { return () => {
@@ -52,21 +52,21 @@ const ParamsSettings: React.FC<ParamsSettingsProps> = ({
useEffect(() => { useEffect(() => {
if (showModelSelector) { if (showModelSelector) {
form.setFieldsValue({ form.setFieldsValue({
model: selectedModel || _.get(modelList, '[0].value'), ...initialValues,
...initialValues model: selectedModel || _.get(modelList, '[0].value')
}); });
setParams({ setParams({
model: selectedModel || _.get(modelList, '[0].value'), ...initialValues,
...initialValues model: selectedModel || _.get(modelList, '[0].value')
}); });
} else { } else {
form.setFieldsValue({ form.setFieldsValue({
model: selectedModel || '', ...initialValues,
...initialValues model: selectedModel || ''
}); });
setParams({ setParams({
model: selectedModel || '', ...initialValues,
...initialValues model: selectedModel || ''
}); });
} }
}, [modelList, showModelSelector, selectedModel]); }, [modelList, showModelSelector, selectedModel]);
+1 -1
View File
@@ -86,7 +86,7 @@
height: fit-content; height: fit-content;
top: -10px; top: -10px;
font-size: var(--font-size-middle); font-size: var(--font-size-middle);
left: 50%; left: calc(50% + 18px);
transform: translateX(-50%); transform: translateX(-50%);
background-color: transparent; background-color: transparent;
} }
+7 -4
View File
@@ -1,7 +1,8 @@
import qs from 'query-string'; import qs from 'query-string';
const extractStreamRegx = /data:\s*({.*?})(?=\n|$)/g;
const extractJSON = (dataStr: string) => { const extractJSON = (dataStr: string) => {
const regex = /data:\s*({.*?})(?=\n|$)/g;
let match; let match;
const results: any[] = []; const results: any[] = [];
@@ -9,9 +10,10 @@ const extractJSON = (dataStr: string) => {
return results; return results;
} }
while ((match = regex.exec(dataStr)) !== null) { while ((match = extractStreamRegx.exec(dataStr)) !== null) {
try { try {
results.push(JSON.parse(match[1])); const jsonData = JSON.parse(match[1]);
results.push(jsonData);
} catch (error) { } catch (error) {
console.error('JSON parse error:', error, 'for match:', match[1]); console.error('JSON parse error:', error, 'for match:', match[1]);
@@ -21,6 +23,7 @@ const extractJSON = (dataStr: string) => {
return results; return results;
}; };
/** /**
* *
* @param params data: for post request, params: for get request * @param params data: for post request, params: for get request
@@ -74,8 +77,8 @@ export const readStreamData = async (
} }
let chunk = decoder.decode(value, { stream: true }); let chunk = decoder.decode(value, { stream: true });
console.log('chunk==========', chunk);
extractJSON(chunk).forEach((data) => { extractJSON(chunk).forEach((data) => {
console.log('data====', data);
callback?.(data); callback?.(data);
}); });
// callback(chunk); // callback(chunk);