From 3ab29f9e018d27600858d40eab0d2ee15ac3f844 Mon Sep 17 00:00:00 2001 From: jialin Date: Sun, 22 Sep 2024 11:58:30 +0800 Subject: [PATCH] feat: modelscope model --- config/proxy.ts | 2 +- src/components/icon-font/index.tsx | 2 +- src/config/hotkeys.ts | 1 + src/global.less | 3 - src/layouts/index.tsx | 1 + src/locales/en-US/models.ts | 3 +- src/locales/zh-CN/models.ts | 3 +- src/pages/llmodels/apis/index.ts | 75 +++++++- src/pages/llmodels/components/data-form.tsx | 61 +++--- .../llmodels/components/deploy-modal.tsx | 76 ++++---- .../llmodels/components/hf-model-file.tsx | 73 ++++++-- .../llmodels/components/hf-model-item.tsx | 7 +- src/pages/llmodels/components/model-card.tsx | 116 +++++++++--- .../llmodels/components/search-input.tsx | 36 ++-- .../llmodels/components/search-model.tsx | 175 +++++++++--------- .../llmodels/components/search-result.tsx | 6 +- src/pages/llmodels/components/table-list.tsx | 64 +++++-- .../llmodels/components/update-modal.tsx | 55 ++++-- src/pages/llmodels/config/index.ts | 76 +++++++- src/pages/llmodels/config/types.ts | 6 + .../playground/components/ground-left.tsx | 8 +- .../components/multiple-chat/index.tsx | 1 - .../components/multiple-chat/model-item.tsx | 52 +++--- src/request-config.ts | 2 +- 24 files changed, 618 insertions(+), 286 deletions(-) diff --git a/config/proxy.ts b/config/proxy.ts index 39dccc71..152f3259 100644 --- a/config/proxy.ts +++ b/config/proxy.ts @@ -1,4 +1,4 @@ -const proxyTableList = ['cli', 'v1', 'auth', 'v1-openai', 'version']; +const proxyTableList = ['cli', 'v1', 'auth', 'v1-openai', 'version', 'proxy']; // @ts-ingore export default function createProxyTable(target?: string) { diff --git a/src/components/icon-font/index.tsx b/src/components/icon-font/index.tsx index 98887b2b..9c91958e 100644 --- a/src/components/icon-font/index.tsx +++ b/src/components/icon-font/index.tsx @@ -1,7 +1,7 @@ import { createFromIconfontCN } from '@ant-design/icons'; const IconFont = createFromIconfontCN({ - scriptUrl: '//at.alicdn.com/t/c/font_4613488_7vr8v36d7xp.js' + scriptUrl: '//at.alicdn.com/t/c/font_4613488_4jkdkc8jcf7.js' }); export default IconFont; diff --git a/src/config/hotkeys.ts b/src/config/hotkeys.ts index e04f5265..083ae60d 100644 --- a/src/config/hotkeys.ts +++ b/src/config/hotkeys.ts @@ -19,6 +19,7 @@ const KeybindingsMap = { INPUT: ['Ctrl+K', 'Meta+K'], NEW1: ['Ctrl+1', 'Meta+1'], NEW2: ['Ctrl+2', 'Meta+2'], + NEW3: ['Ctrl+3', 'Meta+3'], FOCUS: ['/', '/'], ADD: ['Alt+Ctrl+Enter', 'Alt+Meta+Enter'] }; diff --git a/src/global.less b/src/global.less index cea07b16..0048ecb3 100644 --- a/src/global.less +++ b/src/global.less @@ -153,9 +153,6 @@ html { body * { font-weight: var(--font-weight-normal); - font-family: 'noto sans', sans-serif; - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; } body { diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index bac25311..bd798063 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -176,6 +176,7 @@ export default (props: any) => { {logo}
+ + ); + } + + if (modelSource === modelSourceMap.modelscope_value) { + return ( + + + + ); + } + return null; + }; + useEffect(() => { getModelCardData(); - }, [repo]); + }, [props.selectedModel.name]); useEffect(() => { if (!readmeText) { @@ -98,19 +173,8 @@ const ModelCard: React.FC<{ return ( <> -
{modelData?.id}
- {modelData?.id && ( - - - - )} +
{modelData?.id || modelData?.name}
+ {generateModelLink()}
{modelData ? ( diff --git a/src/pages/llmodels/components/search-input.tsx b/src/pages/llmodels/components/search-input.tsx index 767f6737..698c6954 100644 --- a/src/pages/llmodels/components/search-input.tsx +++ b/src/pages/llmodels/components/search-input.tsx @@ -1,41 +1,51 @@ +import IconFont from '@/components/icon-font'; import hotkeys from '@/config/hotkeys'; -import { SearchOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import { Input } from 'antd'; -import React, { useRef, useState } from 'react'; +import React, { useRef } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; +import { modelSourceMap, modelSourceValueMap } from '../config'; const SearchInput: React.FC<{ + modelSource: string; onSearch: (e: any) => void; }> = (props) => { - const { onSearch } = props; + const { onSearch, modelSource } = props; const intl = useIntl(); - const [isFocus, setIsFocus] = useState(false); const inputRef = useRef(null); - useHotkeys(hotkeys.INPUT.join(','), () => { + useHotkeys(hotkeys.FOCUS, (e: any) => { + e.preventDefault(); inputRef.current?.focus?.(); - setIsFocus(true); }); return ( setIsFocus(true)} - onBlur={() => setIsFocus(false)} allowClear - placeholder={intl.formatMessage({ - id: 'model.deploy.search.placeholder' - })} + placeholder={intl.formatMessage( + { + id: 'model.deploy.search.placeholder' + }, + { source: modelSourceValueMap[modelSource] } + )} prefix={ <> - + /> */} + } > diff --git a/src/pages/llmodels/components/search-model.tsx b/src/pages/llmodels/components/search-model.tsx index f8083116..ad60365a 100644 --- a/src/pages/llmodels/components/search-model.tsx +++ b/src/pages/llmodels/components/search-model.tsx @@ -1,10 +1,15 @@ import { BulbOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Input, Select } from 'antd'; +import { Select } from 'antd'; import _ from 'lodash'; import React, { useCallback, useEffect, useRef, useState } from 'react'; -import { queryHuggingfaceModels } from '../apis'; -import { ModelSortType, modelSourceMap, ollamaModelOptions } from '../config'; +import { queryHuggingfaceModels, queryModelScopeModels } from '../apis'; +import { + ModelScopeSortType, + ModelSortType, + modelSourceMap, + ollamaModelOptions +} from '../config'; import SearchStyle from '../style/search-result.less'; import SearchInput from './search-input'; import SearchResult from './search-result'; @@ -31,10 +36,13 @@ const SearchModel: React.FC = (props) => { networkError: false, sortType: ModelSortType.trendingScore }); + const SUPPORTEDSOURCE = [ + modelSourceMap.huggingface_value, + modelSourceMap.modelscope_value + ]; const [current, setCurrent] = useState(''); const cacheRepoOptions = useRef([]); const axiosTokenRef = useRef(null); - const customOllamaModelRef = useRef(null); const searchInputRef = useRef(''); const modelFilesSortOptions = useRef([ { @@ -56,16 +64,74 @@ const SearchModel: React.FC = (props) => { ]); const handleOnSelectModel = useCallback((item: any) => { + console.log('handleOnSelectModel', item); onSelectModel(item); setCurrent(item.id); }, []); + // huggeface + const getModelsFromHuggingface = useCallback(async (sort: string) => { + try { + const task: any = searchInputRef.current ? '' : 'text-generation'; + const params = { + search: { + query: searchInputRef.current || '', + sort: sort, + tags: ['gguf'], + task + } + }; + const data = await queryHuggingfaceModels(params, { + signal: axiosTokenRef.current.signal + }); + let list = _.map(data || [], (item: any) => { + return { + ...item, + value: item.name, + label: item.name + }; + }); + return list; + } catch (error) { + return []; + } + }, []); + + // modelscope + const getModelsFromModelscope = useCallback(async (sort: string) => { + try { + const params = { + Name: searchInputRef.current || '', + SortBy: ModelScopeSortType[sort] + }; + const data = await queryModelScopeModels(params, { + signal: axiosTokenRef.current.signal + }); + let list = _.map(_.get(data, 'Data.Model.Models') || [], (item: any) => { + return { + path: item.Path, + name: `${item.Path}/${item.Name}`, + downloads: item.Downloads, + id: item.Name, + updatedAt: item.LastUpdatedTime * 1000, + likes: item.Stars, + value: item.Name, + label: item.Name, + task: item.Tasks?.map((sItem: any) => sItem.Name).join(',') + }; + }); + + return list; + } catch (error) { + return []; + } + }, []); + const handleOnSearchRepo = useCallback( async (sortType?: string) => { - if (modelSource === modelSourceMap.ollama_library_value) { + if (!SUPPORTEDSOURCE.includes(modelSource)) { return; } - console.log('handleOnSearchRepo', dataSource.loading); axiosTokenRef.current?.abort?.(); axiosTokenRef.current = new AbortController(); if (dataSource.loading) return; @@ -77,26 +143,12 @@ const SearchModel: React.FC = (props) => { }); setLoadingModel?.(true); cacheRepoOptions.current = []; - const task: any = searchInputRef.current ? '' : 'text-generation'; - const params = { - search: { - query: searchInputRef.current || '', - sort: sort, - tags: ['gguf'], - task - } - }; - const models = await queryHuggingfaceModels(params, { - signal: axiosTokenRef.current.signal - }); - let list = _.map(models || [], (item: any) => { - return { - ...item, - value: item.name, - label: item.name - }; - }); - + let list: any[] = []; + if (modelSource === modelSourceMap.huggingface_value) { + list = await getModelsFromHuggingface(sort); + } else if (modelSource === modelSourceMap.modelscope_value) { + list = await getModelsFromModelscope(sort); + } cacheRepoOptions.current = list; setDataSource({ repoOptions: list, @@ -133,7 +185,7 @@ const SearchModel: React.FC = (props) => { if ( !dataSource.repoOptions.length && !cacheRepoOptions.current.length && - modelSource === modelSourceMap.huggingface_value + SUPPORTEDSOURCE.includes(modelSource) ) { handleOnSearchRepo(); } @@ -149,51 +201,6 @@ const SearchModel: React.FC = (props) => { } }; - const handleFilterModels = (e: any) => { - const text = e.target.value; - const list = _.filter(cacheRepoOptions.current, (item: any) => { - return item.name.includes(text); - }); - setDataSource({ - repoOptions: list, - loading: false, - networkError: false, - sortType: dataSource.sortType - }); - }; - - const debounceFilter = _.debounce((e: any) => { - handleFilterModels(e); - }, 300); - - const handleSourceChange = (source: string) => { - axiosTokenRef.current?.abort?.(); - onSourceChange?.(source); - setDataSource({ - repoOptions: [], - loading: false, - networkError: false, - sortType: dataSource.sortType - }); - cacheRepoOptions.current = []; - }; - - const handleInputChange = (e: any) => { - const value = e.target.value; - customOllamaModelRef.current = value; - }; - - const handleConfirm = () => { - const model = { - label: customOllamaModelRef.current, - value: customOllamaModelRef.current, - name: customOllamaModelRef.current, - id: '' - }; - onSelectModel(model); - setCurrent(''); - }; - const handleSortChange = (value: string) => { handleOnSearchRepo(value || ''); }; @@ -201,7 +208,10 @@ const SearchModel: React.FC = (props) => { const renderHFSearch = () => { return ( <> - +
@@ -231,23 +241,6 @@ const SearchModel: React.FC = (props) => { ); }; - const renderOllamaCustom = () => { - return ( - <> - -
- -
- - ); - }; - useEffect(() => { handleOnOpen(); console.log('SearchModel useEffect', modelSource); @@ -262,7 +255,7 @@ const SearchModel: React.FC = (props) => { return (
- {modelSource === modelSourceMap.huggingface_value ? ( + {SUPPORTEDSOURCE.includes(modelSource) ? ( renderHFSearch() ) : (
diff --git a/src/pages/llmodels/components/search-result.tsx b/src/pages/llmodels/components/search-result.tsx index eb647187..0bd5101f 100644 --- a/src/pages/llmodels/components/search-result.tsx +++ b/src/pages/llmodels/components/search-result.tsx @@ -1,7 +1,7 @@ import IconFont from '@/components/icon-font'; import { SearchOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Col, Empty, Row, Spin } from 'antd'; +import { Col, Empty, Row, Spin } from 'antd'; import React from 'react'; import SimpleBar from 'simplebar-react'; import 'simplebar-react/dist/simplebar.min.css'; @@ -53,7 +53,7 @@ const SearchResult: React.FC = (props) => { {intl.formatMessage({ id: 'models.search.networkerror' })} - + {/* {intl.formatMessage({ id: 'models.search.hfvisit' })} @@ -65,7 +65,7 @@ const SearchResult: React.FC = (props) => { > Hugging Face - + */}
} /> diff --git a/src/pages/llmodels/components/table-list.tsx b/src/pages/llmodels/components/table-list.tsx index 4a626cb4..df4e6090 100644 --- a/src/pages/llmodels/components/table-list.tsx +++ b/src/pages/llmodels/components/table-list.tsx @@ -38,7 +38,7 @@ import { queryModelInstancesList, updateModel } from '../apis'; -import { modelSourceMap } from '../config'; +import { getSourceRepoConfigValue, modelSourceMap } from '../config'; import { FormData, ListItem, ModelInstanceListItem } from '../config/types'; import DeployModal from './deploy-modal'; import InstanceItem from './instance-item'; @@ -95,9 +95,7 @@ const Models: React.FC = ({ source: modelSourceMap.huggingface_value }); const [title, setTitle] = useState(''); - const [currentData, setCurrentData] = useState( - undefined - ); + const [currentData, setCurrentData] = useState({} as ListItem); const [currentInstanceUrl, setCurrentInstanceUrl] = useState(''); const modalRef = useRef(null); @@ -116,6 +114,21 @@ const Models: React.FC = ({ } ); + useHotkeys( + HotKeys.NEW3.join(','), + () => { + setOpenDeployModal({ + show: true, + width: 'calc(100vw - 220px)', + source: modelSourceMap.modelscope_value + }); + }, + { + preventDefault: true, + enabled: !openAddModal && !openDeployModal.show && !openLogModal + } + ); + useHotkeys( HotKeys.NEW2.join(','), () => { @@ -159,6 +172,19 @@ const Models: React.FC = ({ }; }); } + }, + { + label: 'ModelScope', + value: modelSourceMap.modelscope_value, + key: 'modelscope', + icon: , + onClick: (e: any) => { + setOpenDeployModal({ + show: true, + width: 'calc(100vw - 220px)', + source: modelSourceMap.modelscope_value + }); + } } ]; @@ -222,9 +248,12 @@ const Models: React.FC = ({ const handleModalOk = useCallback( async (data: FormData) => { try { + console.log('data:', data, openDeployModal); + const result = getSourceRepoConfigValue(currentData?.source, data); await updateModel({ data: { - ...data + ...result.values, + ..._.omit(data, result.omits) }, id: currentData?.id as number }); @@ -252,7 +281,14 @@ const Models: React.FC = ({ try { console.log('data:', data, openDeployModal); - await createModel({ data }); + const result = getSourceRepoConfigValue(openDeployModal.source, data); + + await createModel({ + data: { + ...result.values, + ..._.omit(data, result.omits) + } + }); setOpenDeployModal({ ...openDeployModal, show: false @@ -380,6 +416,16 @@ const Models: React.FC = ({ [workerList] ); + const generateSource = useCallback((record: ListItem) => { + if (record.source === modelSourceMap.modelscope_value) { + return `${modelSourceMap.modelScope} / ${record.model_scope_file_path}`; + } + if (record.source === modelSourceMap.huggingface_value) { + return `${modelSourceMap.huggingface} / ${record.huggingface_filename}`; + } + return `${modelSourceMap.ollama_library} / ${record.ollama_library_model_name}`; + }, []); + const handleCloseViewCode = useCallback(() => { setEmbeddingParams({ params: {}, @@ -493,11 +539,7 @@ const Models: React.FC = ({ render={(text, record: ListItem) => { return ( - - {record.source === modelSourceMap.huggingface_value - ? `${modelSourceMap.huggingface} / ${record.huggingface_filename}` - : `${modelSourceMap.ollama_library} / ${record.ollama_library_model_name}`} - + {generateSource(record)} ); }} diff --git a/src/pages/llmodels/components/update-modal.tsx b/src/pages/llmodels/components/update-modal.tsx index 82ed324e..fcd24ee3 100644 --- a/src/pages/llmodels/components/update-modal.tsx +++ b/src/pages/llmodels/components/update-modal.tsx @@ -8,11 +8,11 @@ import { convertFileSize } from '@/utils'; import { useIntl } from '@umijs/max'; import { Form, Modal } from 'antd'; import _ from 'lodash'; -import { memo, useEffect, useState } from 'react'; +import { memo, useEffect, useMemo, useState } from 'react'; import SimpleBar from 'simplebar-react'; import 'simplebar-react/dist/simplebar.min.css'; import { queryGPUList, queryHuggingfaceModelFiles } from '../apis'; -import { modelSourceMap } from '../config'; +import { modelSourceMap, setSourceRepoConfigValue } from '../config'; import { FormData, GPUListItem, ListItem } from '../config/types'; import AdvanceConfig from './advance-config'; @@ -35,9 +35,19 @@ const sourceOptions = [ label: 'Ollama Library', value: modelSourceMap.ollama_library_value, key: 'ollama_library' + }, + { + label: 'ModelScope', + value: modelSourceMap.modelscope_value, + key: 'model_scope' } ]; +const SEARCH_SOURCE = [ + modelSourceMap.huggingface_value, + modelSourceMap.modelscope_value +]; + const UpdateModal: React.FC = (props) => { console.log('addmodel===='); const { title, action, open, onOk, onCancel } = props || {}; @@ -70,8 +80,13 @@ const UpdateModal: React.FC = (props) => { }); } if (action === PageAction.EDIT && open) { + const result = setSourceRepoConfigValue( + props.data?.source || '', + props.data + ); form.setFieldsValue({ - ...props.data, + ...result.values, + ..._.omit(props.data, result.omits), scheduleType: props.data?.gpu_selector ? 'manual' : 'auto', gpu_selector: props.data?.gpu_selector ? `${props.data?.gpu_selector.worker_name}-${props.data?.gpu_selector.gpu_name}-${props.data?.gpu_selector.gpu_index}` @@ -118,7 +133,7 @@ const UpdateModal: React.FC = (props) => { }; const handleRepoOnBlur = (e: any) => { - const repo = form.getFieldValue('huggingface_repo_id'); + const repo = form.getFieldValue('repo_id'); handleFetchModelFiles(repo); }; @@ -126,7 +141,7 @@ const UpdateModal: React.FC = (props) => { return ( <> - name="huggingface_repo_id" + name="repo_id" rules={[ { required: true, @@ -146,7 +161,7 @@ const UpdateModal: React.FC = (props) => { > - name="huggingface_filename" + name="file_name" rules={[ { required: true, @@ -165,7 +180,6 @@ const UpdateModal: React.FC = (props) => { required options={fileOptions} loading={loading} - onFocus={handleRepoOnBlur} disabled={action === PageAction.EDIT} > @@ -229,18 +243,21 @@ const UpdateModal: React.FC = (props) => { ); }; - const renderFieldsBySource = () => { - switch (modelSource) { - case modelSourceMap.huggingface_value: - return renderHuggingfaceFields(); - case modelSourceMap.ollama_library_value: - return renderOllamaModelFields(); - case modelSourceMap.s3_value: - return renderS3Fields(); - default: - return null; + const renderFieldsBySource = useMemo(() => { + if (SEARCH_SOURCE.includes(props.data?.source || '')) { + return renderHuggingfaceFields(); } - }; + + if (props.data?.source === modelSourceMap.ollama_library_value) { + return renderOllamaModelFields(); + } + + if (props.data?.source === modelSourceMap.s3_value) { + return renderS3Fields(); + } + + return null; + }, [props.data?.source]); const handleSumit = () => { form.submit(); @@ -367,7 +384,7 @@ const UpdateModal: React.FC = (props) => { > )} - {renderFieldsBySource()} + {renderFieldsBySource} name="replicas" rules={[ diff --git a/src/pages/llmodels/config/index.ts b/src/pages/llmodels/config/index.ts index d174c6f5..34b5d419 100644 --- a/src/pages/llmodels/config/index.ts +++ b/src/pages/llmodels/config/index.ts @@ -87,7 +87,16 @@ export const modelSourceMap: Record = { s3: 'S3', huggingface_value: 'huggingface', ollama_library_value: 'ollama_library', - s3_value: 's3' + s3_value: 's3', + modelScope: 'ModelScope', + modelscope_value: 'model_scope' +}; + +export const modelSourceValueMap = { + [modelSourceMap.huggingface_value]: modelSourceMap.huggingface, + [modelSourceMap.ollama_library_value]: modelSourceMap.ollama_library, + [modelSourceMap.s3_value]: modelSourceMap.s3, + [modelSourceMap.modelscope_value]: modelSourceMap.modelScope }; export const InstanceStatusMap = { @@ -148,6 +157,13 @@ export const ModelSortType = { lastModified: 'lastModified' }; +export const ModelScopeSortType = { + [ModelSortType.trendingScore]: 'Default', + [ModelSortType.likes]: 'StarsCount', + [ModelSortType.downloads]: 'DownloadsCount', + [ModelSortType.lastModified]: 'GmtModified' +}; + export const placementStrategyOptions = [ { label: 'Spread', @@ -158,3 +174,61 @@ export const placementStrategyOptions = [ value: 'binpack' } ]; + +export const sourceRepoConfig = { + [modelSourceMap.huggingface_value]: { + repo_id: 'huggingface_repo_id', + file_name: 'huggingface_filename' + }, + + [modelSourceMap.modelscope_value]: { + repo_id: 'model_scope_model_id', + file_name: 'model_scope_file_path' + } +}; + +export const getSourceRepoConfigValue = ( + source: string, + data: any +): { + values: Record; + omits: string[]; +} => { + const config: Record = sourceRepoConfig[source] || {}; + const result: Record = {}; + const omits: string[] = []; + Object.keys(config)?.forEach((key: string) => { + if (config[key]) { + result[config[key]] = data[key]; + omits.push(key); + } + }); + + return { + values: result, + omits: omits + }; +}; + +export const setSourceRepoConfigValue = ( + source: string, + data: any +): { + values: Record; + omits: string[]; +} => { + const config: Record = sourceRepoConfig[source] || {}; + const result: Record = {}; + const omits: string[] = []; + Object.keys(config)?.forEach((key: string) => { + if (config[key]) { + result[key] = data[config[key]]; + omits.push(config[key]); + } + }); + + return { + values: result, + omits: omits + }; +}; diff --git a/src/pages/llmodels/config/types.ts b/src/pages/llmodels/config/types.ts index 657fb3ef..5500cdf8 100644 --- a/src/pages/llmodels/config/types.ts +++ b/src/pages/llmodels/config/types.ts @@ -4,6 +4,8 @@ export interface ListItem { huggingface_file_name: string; huggingface_filename: string; ollama_library_model_name: string; + model_scope_file_path: string; + model_scope_model_id: string; embedding_only?: boolean; ready_replicas: number; replicas: number; @@ -23,11 +25,15 @@ export interface ListItem { export interface FormData { source: string; + repo_id: string; + file_name: string; huggingface_repo_id: string; huggingface_filename: string; s3_address: string; ollama_library_model_name: 'string'; distributed_inference_across_workers?: boolean; + model_scope_model_id?: string; + model_scope_file_path?: string; gpu_selector?: { worker_name: string; gpu_index: number; diff --git a/src/pages/playground/components/ground-left.tsx b/src/pages/playground/components/ground-left.tsx index 211566b2..53c75138 100644 --- a/src/pages/playground/components/ground-left.tsx +++ b/src/pages/playground/components/ground-left.tsx @@ -26,7 +26,6 @@ import ReferenceParams from './reference-params'; import ViewCodeModal from './view-code-modal'; interface MessageProps { - parameters?: any; modelList: Global.BaseOption[]; ref?: any; } @@ -142,10 +141,6 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { ] : []; - setMessageList((pre) => { - return [...pre, ...currentMessageRef.current]; - }); - contentRef.current = ''; const formatMessages = _.map( [...messageList, ...currentMessageRef.current], @@ -207,6 +202,9 @@ const GroundLeft: React.FC = forwardRef((props, ref) => { setLoading(false); } catch (error) { console.log('error=====', error); + setMessageList((pre) => { + return [...pre, ...currentMessageRef.current]; + }); setLoading(false); } }; diff --git a/src/pages/playground/components/multiple-chat/index.tsx b/src/pages/playground/components/multiple-chat/index.tsx index 22a44ae1..2424baa2 100644 --- a/src/pages/playground/components/multiple-chat/index.tsx +++ b/src/pages/playground/components/multiple-chat/index.tsx @@ -34,7 +34,6 @@ const MultiCompare: React.FC = ({ modelList }) => { span: 12, count: 2 }); - const cacheModelInstanceList = useRef([]); const modelsCounterMap = useRef>({}); const modelRefs = useRef({}); const boxHeight = 'calc(100vh - 72px)'; diff --git a/src/pages/playground/components/multiple-chat/model-item.tsx b/src/pages/playground/components/multiple-chat/model-item.tsx index e7f346f7..e3b828bb 100644 --- a/src/pages/playground/components/multiple-chat/model-item.tsx +++ b/src/pages/playground/components/multiple-chat/model-item.tsx @@ -60,7 +60,7 @@ const ModelItem: React.FC = forwardRef( const [show, setShow] = useState(false); const contentRef = useRef(''); const controllerRef = useRef(null); - const currentMessageRef = useRef({} as MessageItem); + const currentMessageRef = useRef([]); const setMessageId = () => { messageId.current = messageId.current + 1; @@ -94,6 +94,7 @@ const ModelItem: React.FC = forwardRef( console.log('currentMessage==========5', messageList); setMessageList([ ...messageList, + ...currentMessageRef.current, { role: Roles.Assistant, content: contentRef.current, @@ -102,13 +103,8 @@ const ModelItem: React.FC = forwardRef( ]); }; - const submitMessage = async (currentParams: { - parameters: Record; - currentMessage: Omit; - }) => { - console.log('currentMessage==========3', currentParams); - const { parameters, currentMessage } = currentParams; - if (!parameters.model) return; + const submitMessage = async (currentMessage?: Omit) => { + if (!params.model) return; try { setLoadingStatus(instanceId, true); setMessageId(); @@ -116,26 +112,18 @@ const ModelItem: React.FC = forwardRef( controllerRef.current?.abort?.(); controllerRef.current = new AbortController(); const signal = controllerRef.current.signal; - currentMessageRef.current = { - ...currentMessage, - uid: messageId.current - }; - setMessageList((preList) => { - return [ - ...preList, - { - ...currentMessageRef.current - } - ]; - }); + currentMessageRef.current = currentMessage + ? [ + { + ...currentMessage, + uid: messageId.current + } + ] + : []; + console.log('currentMessageRef.current 1:', currentMessageRef.current); console.log('currentMessage==========4', messageList); const messages = _.map( - [ - ...messageList, - { - ...currentMessageRef.current - } - ], + [...messageList, ...currentMessageRef.current], (item: MessageItem) => { return { role: item.role, @@ -184,7 +172,7 @@ const ModelItem: React.FC = forwardRef( ...formatMessages ] : [...formatMessages], - ...parameters, + ...params, stream: true }; // ============== payload end ================ @@ -204,6 +192,9 @@ const ModelItem: React.FC = forwardRef( }); setLoadingStatus(instanceId, false); } catch (error) { + setMessageList((preList) => { + return [...preList, ...currentMessageRef.current]; + }); setLoadingStatus(instanceId, false); } }; @@ -222,7 +213,8 @@ const ModelItem: React.FC = forwardRef( content: string; }) => { console.log('currentMessage==========2', currentMessage); - submitMessage({ parameters: params, currentMessage }); + const currentMsg = currentMessage.content ? currentMessage : undefined; + submitMessage(currentMsg); }; const handleApplyToAllModels = (e: any) => { @@ -260,7 +252,7 @@ const ModelItem: React.FC = forwardRef( setMessageList([]); setTokenResult(null); setSystemMessage(''); - currentMessageRef.current = {} as MessageItem; + currentMessageRef.current = []; console.log('clear message', systemMessage); }; @@ -277,7 +269,7 @@ const ModelItem: React.FC = forwardRef( }; const handlePresetMessageList = (list: MessageItem[]) => { - currentMessageRef.current = {} as MessageItem; + currentMessageRef.current = []; const messages = _.map(list, (item: Omit) => { setMessageId(); return { diff --git a/src/request-config.ts b/src/request-config.ts index 186f20f7..c06e31c9 100644 --- a/src/request-config.ts +++ b/src/request-config.ts @@ -3,7 +3,7 @@ import { clearAtomStorage } from '@/atoms/utils'; import { RequestConfig, history } from '@umijs/max'; import { message } from 'antd'; -const NoBaseURLAPIs = ['/auth', '/v1-openai', '/version']; +const NoBaseURLAPIs = ['/auth', '/v1-openai', '/version', '/proxy']; export const requestConfig: RequestConfig = { errorConfig: {