diff --git a/src/components/icon-font/index.tsx b/src/components/icon-font/index.tsx index 58e12960..9aab093d 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_xpmv3m9655d.js' + scriptUrl: '//at.alicdn.com/t/c/font_4613488_fcpq8y25444.js' }); export default IconFont; diff --git a/src/components/seal-form/components/wrapper.less b/src/components/seal-form/components/wrapper.less index ff82874e..be7911c7 100644 --- a/src/components/seal-form/components/wrapper.less +++ b/src/components/seal-form/components/wrapper.less @@ -1,5 +1,5 @@ :local(.wrapper-box) { - @borderRadius: 8px; + @borderRadius: var(--border-radius-base); position: relative; display: flex; diff --git a/src/pages/playground/components/message-input.tsx b/src/pages/playground/components/message-input.tsx index dba561fc..f480476c 100644 --- a/src/pages/playground/components/message-input.tsx +++ b/src/pages/playground/components/message-input.tsx @@ -5,13 +5,16 @@ import { ClearOutlined, ControlOutlined, PictureOutlined, - SendOutlined + SendOutlined, + SwapOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Input, Select } from 'antd'; +import { Button, Divider, Input, Select } from 'antd'; import { useState } from 'react'; import { useHotkeys } from 'react-hotkeys-hook'; +import { Roles } from '../config'; import '../style/message-input.less'; +import PromptModal from './prompt-modal'; const layoutOptions = [ { @@ -36,7 +39,7 @@ const layoutOptions = [ label: '4 columns', icon: 'icon-cols_4', value: { - span: 6, + span: 12, count: 4 }, tips: 'four models compare' @@ -54,31 +57,47 @@ const layoutOptions = [ interface MessageInputProps { modelList: Global.BaseOption[]; - handleSubmit: (value: string) => void; + handleSubmit: (params: { role: string; content: string }) => void; handleAbortFetch: () => void; - setParamsSettings: (value: Record) => void; setSpans: (value: { span: number; count: number }) => void; + clearAll: () => void; + setModelSelections: (modelList: Global.BaseOption[]) => void; + presetPrompt: (list: { role: string; content: string }[]) => void; loading: boolean; } const MessageInput: React.FC = ({ handleSubmit, handleAbortFetch, - setParamsSettings, + setModelSelections, + presetPrompt, loading, modelList, + clearAll, setSpans }) => { const { TextArea } = Input; const intl = useIntl(); const platform = platformCall(); const [disabled, setDisabled] = useState(false); - const [message, setMessage] = useState(''); + const [open, setOpen] = useState(false); + const [message, setMessage] = useState<{ role: string; content: string }>({ + role: Roles.User, + content: '' + }); const handleInputChange = (value: string) => { - setMessage(value); + console.log('input change:', value); + setMessage({ + ...message, + content: value + }); }; const handleSendMessage = () => { - handleSubmit(message); + handleSubmit({ ...message }); + setMessage({ + ...message, + content: '' + }); }; const onStop = () => { setDisabled(false); @@ -88,6 +107,33 @@ const MessageInput: React.FC = ({ console.log('layout change:', value); setSpans(value); }; + + const handleToggleRole = () => { + setMessage({ + ...message, + role: message.role === Roles.User ? Roles.Assistant : Roles.User + }); + }; + + const handleClearAll = (e: any) => { + e.stopPropagation(); + clearAll(); + }; + + const handleUpdateModelSelections = (value: string[]) => { + console.log('update model selections:', value); + const list = value?.map?.((val) => { + return { + value: val, + label: val + }; + }); + setModelSelections(list); + }; + + const handleOpenPrompt = () => { + setOpen(true); + }; useHotkeys( HotKeys.SUBMIT.join(','), () => { @@ -99,10 +145,29 @@ const MessageInput: React.FC = ({
+ + - - - + + + {layoutOptions.map((option) => ( ) : (
+ setOpen(false)} + onSelect={presetPrompt} + >
); }; diff --git a/src/pages/playground/components/multiple-chat/active-models.tsx b/src/pages/playground/components/multiple-chat/active-models.tsx new file mode 100644 index 00000000..743366e6 --- /dev/null +++ b/src/pages/playground/components/multiple-chat/active-models.tsx @@ -0,0 +1,34 @@ +import { Col, Row } from 'antd'; +import React from 'react'; +import ModelItem from './model-item'; + +interface ActiveModelsProps { + spans: { + span: number; + count: number; + }; + modelSelections: Global.BaseOption[]; + setModelRefs: (modelname: string, value: React.MutableRefObject) => void; +} + +const ActiveModels: React.FC = (props) => { + const { spans, modelSelections, setModelRefs } = props; + return ( + + {modelSelections.map((model, index) => ( + + ) => + setModelRefs(model.value, el) + } + modelList={modelSelections} + model={model.value} + /> + + ))} + + ); +}; + +export default React.memo(ActiveModels); diff --git a/src/pages/playground/components/multiple-chat/content-item.tsx b/src/pages/playground/components/multiple-chat/content-item.tsx index e1d53ca6..bb1d5bf6 100644 --- a/src/pages/playground/components/multiple-chat/content-item.tsx +++ b/src/pages/playground/components/multiple-chat/content-item.tsx @@ -1,5 +1,9 @@ +import IconFont from '@/components/icon-font'; +import { UserOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; import React from 'react'; +import { Roles } from '../../config'; +import '../../style/content-item.less'; const ContentItem: React.FC<{ data: { role: string; content: string } }> = ({ data @@ -8,7 +12,13 @@ const ContentItem: React.FC<{ data: { role: string; content: string } }> = ({ return (
- {' '} + + {Roles.User === data.role ? ( + + ) : ( + + )} + {intl.formatMessage({ id: `playground.${data.role}` })}
{data.content}
diff --git a/src/pages/playground/components/multiple-chat/index.tsx b/src/pages/playground/components/multiple-chat/index.tsx index 07d629aa..2dfd150f 100644 --- a/src/pages/playground/components/multiple-chat/index.tsx +++ b/src/pages/playground/components/multiple-chat/index.tsx @@ -1,24 +1,21 @@ -import { Col, Row } from 'antd'; -import { memo, useEffect, useMemo, useRef, useState } from 'react'; +import _ from 'lodash'; +import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; +import CompareContext from '../../config/compare-context'; import '../../style/multiple-chat.less'; import MessageInput from '../message-input'; -import ModelItem from './model-item'; +import ActiveModels from './active-models'; interface MultiCompareProps { modelList: Global.BaseOption[]; - parmasSettings?: Record; spans?: number; } const MultiCompare: React.FC = ({ modelList }) => { - const [loadingStatus, setLoadingStatus] = useState([]); - const [parmasSettings, setParamsSettings] = useState>({}); - const [systemMessage, setSystemMessage] = useState(''); - const [currentMessage, setCurrentMessage] = useState< - { - role: 'user' | 'assistant'; - content: string; - }[] + const [loadingStatus, setLoadingStatus] = useState>( + {} + ); + const [modelSelections, setModelSelections] = useState< + Global.BaseOption[] >([]); const [globalParams, setGlobalParams] = useState>({ seed: null, @@ -34,88 +31,127 @@ const MultiCompare: React.FC = ({ modelList }) => { span: 12, count: 2 }); - const modelRefs = useRef([]); + const modelRefs = useRef({}); + const boxHeight = 'calc(100vh - 72px)'; const isLoading = useMemo(() => { - return loadingStatus.some((status) => status); + console.log('loadingStatus========2', loadingStatus); + return _.keys(loadingStatus).some( + (modelname: string) => loadingStatus[modelname] + ); }, [loadingStatus]); - const modelSelections = useMemo(() => { + useEffect(() => { const list = modelList.slice?.(0, spans.count); - return list; + setModelSelections(list); }, [modelList, spans.count]); useEffect(() => { - modelRefs.current = modelSelections.map(() => { - return {}; + modelRefs.current = {}; + modelSelections.forEach((item) => { + modelRefs.current[item.value] = null; }); }, [modelSelections]); - const handleSubmit = (message: string) => { - let msg: any[] = []; - if (message) { - msg = [ - { - role: 'user', - content: message - } - ]; - } - modelRefs.current.forEach(async (ref, index) => { - ref?.setMessageList((preList: any) => { - return [...preList, ...msg]; - }); - setLoadingStatus((preStatus) => { - const newState = [...preStatus]; - newState[index] = true; - return newState; - }); - await ref?.submit(); - setLoadingStatus((preStatus) => { - const newState = [...preStatus]; - newState[index] = false; - return newState; - }); + const handleSubmit = (currentMessage: { role: string; content: string }) => { + const modelRefList = _.keys(modelRefs.current); + modelRefList.forEach(async (modelname: any, index: number) => { + const ref = modelRefs.current[modelname]; + ref?.submit(currentMessage); }); }; const handleAbortFetch = () => { - modelRefs.current.forEach((ref) => { + _.keys(modelRefs.current).forEach((modelname: string) => { + const ref = modelRefs.current[modelname]; ref?.abortFetch(); }); }; - const setModelRefs = (index: number, ref: any) => { - modelRefs.current[index] = ref; + const setModelRefs = useCallback( + (modelname: string, el: React.MutableRefObject) => { + modelRefs.current[modelname] = el; + }, + [] + ); + + const handleSetLoadingStatus = (modeName: string, status: boolean) => { + setLoadingStatus((preStatus) => { + const newState = { ...preStatus }; + newState[modeName] = status; + return newState; + }); + }; + + const handleClearAll = () => { + _.keys(modelRefs.current).forEach((modelname: string) => { + const ref = modelRefs.current[modelname]; + ref?.clear(); + }); + }; + + const handleDeleteModel = (modelname: string) => { + const newModelList = modelSelections.filter( + (model) => model.value !== modelname + ); + const span = Math.floor(24 / (24 / spans.span - 1)); + setSpans({ + span, + count: spans.count + }); + setModelSelections(newModelList); + }; + + const handleUpdateModelSelections = (list: Global.BaseOption[]) => { + // set spans.span + const span = Math.floor(24 / list.length); + setSpans({ + span: span < 8 ? 8 : span, + count: spans.count + }); + setModelSelections(list); + }; + + const handlePresetPrompt = (list: { role: string; content: string }[]) => { + const sysMsg = list.filter((item) => item.role === 'system'); + const userMsg = list.filter((item) => item.role === 'user'); + const modelRefList = _.keys(modelRefs.current); + modelRefList.forEach(async (modelname: any) => { + const ref = modelRefs.current[modelname]; + ref?.presetPrompt(userMsg); + ref?.setSystemMessage(_.get(sysMsg, '0.content', '')); + }); }; return ( -
+
- - {modelSelections.map((model, index) => ( - - setModelRefs(index, el)} - modelList={modelSelections} - globalParams={{ - ...globalParams, - model: model.value - }} - systemMessage={systemMessage} - setGlobalParams={setGlobalParams} - /> - - ))} - + + +
diff --git a/src/pages/playground/components/multiple-chat/message-content.tsx b/src/pages/playground/components/multiple-chat/message-content.tsx index 18b28d51..7e0c1d99 100644 --- a/src/pages/playground/components/multiple-chat/message-content.tsx +++ b/src/pages/playground/components/multiple-chat/message-content.tsx @@ -1,21 +1,49 @@ -import React from 'react'; +import { Spin } from 'antd'; +import React, { useMemo } from 'react'; +import SimpleBar from 'simplebar-react'; +import 'simplebar-react/dist/simplebar.min.css'; import ContentItem from './content-item'; interface MessageContentProps { + loading: boolean; + spans: { + span: number; + count: number; + }; messageList: { role: string; - uid?: string; + uid?: any; content: string; }[]; } -const MessageContent: React.FC = ({ messageList }) => { +const MessageContent: React.FC = ({ + messageList, + spans, + loading +}) => { + const maxHeight = useMemo(() => { + const total = 72 + 110 + 46 + 16 + 32; + if (spans.span < 4) { + return `calc(100vh - ${total}px)`; + } + return `calc(100vh - ${total * 2 + 16}px)`; + }, [spans.span]); return ( -
- {messageList.map((item, index) => ( - - ))} -
+ <> + {messageList.length ? ( + +
+ {messageList.map((item, index) => ( + + ))} +
+
+ ) : ( + {loading} + )} + + ); }; diff --git a/src/pages/playground/components/multiple-chat/model-item.tsx b/src/pages/playground/components/multiple-chat/model-item.tsx index 7e056b7b..a9d7311e 100644 --- a/src/pages/playground/components/multiple-chat/model-item.tsx +++ b/src/pages/playground/components/multiple-chat/model-item.tsx @@ -1,4 +1,5 @@ import IconFont from '@/components/icon-font'; +import { fetchChunkedData, readStreamData } from '@/utils/fetch-chunk-data'; import { ClearOutlined, CloseOutlined, @@ -6,71 +7,200 @@ import { SettingOutlined } from '@ant-design/icons'; import { useIntl } from '@umijs/max'; -import { Button, Checkbox, Dropdown, Popover, Select } from 'antd'; +import { + Button, + Checkbox, + Divider, + Dropdown, + Input, + Popover, + Select +} from 'antd'; +import _ from 'lodash'; import React, { forwardRef, + useCallback, + useContext, useEffect, useImperativeHandle, useRef, useState } from 'react'; -import SimpleBar from 'simplebar-react'; import 'simplebar-react/dist/simplebar.min.css'; -import useChatCompletion from '../../hooks/use-chat-completion'; +import { CHAT_API } from '../../apis'; +import { Roles } from '../../config'; +import CompareContext from '../../config/compare-context'; import '../../style/model-item.less'; import ParamsSettings from '../params-settings'; +import ReferenceParams from '../reference-params'; +import ViewCodeModal from '../view-code-modal'; import MessageContent from './message-content'; interface ModelItemProps { - model?: string; - globalParams: Record; - setGlobalParams: (value: Record) => void; + model: string; modelList: Global.BaseOption[]; - systemMessage: string; ref: any; } +interface MessageItemProps { + role: string; + content: string; + uid: string | number; +} + const ModelItem: React.FC = forwardRef( - ({ model, systemMessage, modelList, globalParams, setGlobalParams }, ref) => { + ({ model, modelList }, ref) => { + const { + spans, + globalParams, + setGlobalParams, + setLoadingStatus, + handleDeleteModel, + loadingStatus + } = useContext(CompareContext); const intl = useIntl(); const isApplyToAllModels = useRef(false); + const [autoSize, setAutoSize] = useState<{ + minRows: number; + maxRows: number; + }>({ minRows: 1, maxRows: 1 }); + const [systemMessage, setSystemMessage] = useState(''); const [params, setParams] = useState>({}); - // const [messageList, setMessageList] = useState< - // { - // role: 'user' | 'assistant'; - // content: string; - // }[] - // >([]); - const { messageList, submitMessage, abortFetch, setMessageList, loading } = - useChatCompletion(systemMessage, params); + const [loading, setLoading] = useState(false); + const messageId = useRef(0); + const [messageList, setMessageList] = useState([]); + const [tokenResult, setTokenResult] = useState(null); + const [show, setShow] = useState(false); + const contentRef = useRef(''); + const controllerRef = useRef(null); + const currentMessageRef = useRef({} as MessageItemProps); - useImperativeHandle(ref, () => { - return { - submit: submitMessage, - abortFetch, - setMessageList, - loading - }; - }); + const setMessageId = () => { + messageId.current = messageId.current + 1; + }; - const actions = [ - { - label: intl.formatMessage({ id: 'common.button.clear' }), - key: 'clear', - icon: - }, - { - label: intl.formatMessage({ id: 'playground.viewcode' }), - key: 'viewcode', - icon: + const abortFetch = () => { + controllerRef.current?.abort?.(); + setLoadingStatus(params.model, false); + }; + + const joinMessage = (chunk: any) => { + if (!chunk) { + return; } - ]; + if (_.get(chunk, 'choices.0.finish_reason')) { + setTokenResult({ + ...chunk?.usage + }); + return; + } + contentRef.current = + contentRef.current + _.get(chunk, 'choices.0.delta.content', ''); + console.log('currentMessage==========5', messageList); + setMessageList([ + ...messageList, + { + ...currentMessageRef.current + }, + { + role: Roles.Assistant, + content: contentRef.current, + uid: messageId.current + } + ]); + }; - const handleModelChange = (value: string) => { - setParams({ - ...params, - model: value - }); + const submitMessage = async (currentParams: { + parameters: Record; + currentMessage: { role: string; content: string }; + }) => { + console.log('currentMessage==========3', currentParams); + const { parameters, currentMessage } = currentParams; + if (!parameters.model) return; + try { + setLoadingStatus(parameters.model, true); + setMessageId(); + + controllerRef.current?.abort?.(); + controllerRef.current = new AbortController(); + const signal = controllerRef.current.signal; + currentMessageRef.current = { + ...currentMessage, + uid: messageId.current + }; + setMessageList((preList) => { + return [ + ...preList, + { + ...currentMessageRef.current + } + ]; + }); + console.log('currentMessage==========4', messageList); + const messages = _.map( + [ + ...messageList, + { + ...currentMessageRef.current + } + ], + (item: MessageItemProps) => { + return { + role: item.role, + content: item.content + }; + } + ); + + contentRef.current = ''; + const chatParams = { + messages: systemMessage + ? [ + { + role: Roles.System, + content: systemMessage + }, + ...messages + ] + : [...messages], + ...parameters, + stream: true + }; + const result = await fetchChunkedData({ + data: chatParams, + url: CHAT_API, + signal + }); + + if (!result) { + return; + } + const { reader, decoder } = result; + await readStreamData(reader, decoder, (chunk: any) => { + joinMessage(chunk); + }); + setLoadingStatus(params.model, false); + } catch (error) { + console.log('error=====', error); + setLoadingStatus(params.model, false); + } + }; + const handleDropdownAction = useCallback(({ key }: { key: string }) => { + console.log('key:', key); + if (key === 'clear') { + setMessageList([]); + } + if (key === 'viewCode') { + setShow(true); + } + }, []); + + const handleSubmit = (currentMessage: { + role: string; + content: string; + }) => { + console.log('currentMessage==========2', currentMessage); + submitMessage({ parameters: params, currentMessage }); }; const handleApplyToAllModels = (e: any) => { @@ -104,17 +234,67 @@ const ModelItem: React.FC = forwardRef( } }; - const handleDropdownAction = ({ key }: { key: string }) => { - console.log('key:', key); + const handleClearMessage = () => { + setMessageList([]); + setTokenResult(null); + setSystemMessage(''); + currentMessageRef.current = {} as MessageItemProps; + }; + const handleCloseViewCode = () => { + setShow(false); + }; + + const handleModelChange = (value: string) => { + setParams({ + ...params, + model: value + }); + handleClearMessage(); + }; + + const handlePresetMessageList = (list: MessageItemProps[]) => { + currentMessageRef.current = {} as MessageItemProps; + const messages = _.map( + list, + (item: { role: string; content: string }) => { + setMessageId(); + return { + role: item.role, + content: item.content, + uid: messageId.current + }; + } + ); + setTokenResult(null); + setMessageList(messages); + }; + + const handleDelete = () => { + handleDeleteModel(params.model); + }; + + const handleFocus = () => { + setAutoSize({ + minRows: 4, + maxRows: 4 + }); + }; + + const handleBlur = () => { + setAutoSize({ + minRows: 1, + maxRows: 1 + }); }; useEffect(() => { console.log('globalParams:', globalParams.model, globalParams); setParams({ ...params, + model: model, ...globalParams }); - }, [globalParams]); + }, [globalParams, model]); useEffect(() => { return () => { @@ -122,6 +302,18 @@ const ModelItem: React.FC = forwardRef( }; }, []); + useImperativeHandle(ref, () => { + return { + submit: handleSubmit, + abortFetch, + setMessageList, + clear: handleClearMessage, + presetPrompt: handlePresetMessageList, + setSystemMessage, + loading + }; + }); + return (
@@ -133,9 +325,29 @@ const ModelItem: React.FC = forwardRef( value={params.model} > + , + onClick: () => { + handleDropdownAction({ key: 'clear' }); + } + }, + { + label: intl.formatMessage({ id: 'playground.viewcode' }), + key: 'viewcode', + icon: , + onClick: () => { + handleDropdownAction({ key: 'viewCode' }); + } + } + ] + }} placement="bottomRight" > - +
- -
- -
-
+
+ setSystemMessage(e.target.value)} + > + +
+
+ +
+
); } diff --git a/src/pages/playground/components/prompt-modal.tsx b/src/pages/playground/components/prompt-modal.tsx new file mode 100644 index 00000000..062531bd --- /dev/null +++ b/src/pages/playground/components/prompt-modal.tsx @@ -0,0 +1,80 @@ +import { useIntl } from '@umijs/max'; +import { Button, Modal, Typography } from 'antd'; +import React from 'react'; +import promptList from '../config/prompt'; +import '../style/prompt-modal.less'; + +type ViewModalProps = { + open: boolean; + onCancel: () => void; + onSelect: (list: { role: string; content: string }[]) => void; +}; + +const AddWorker: React.FC = (props) => { + const { open, onCancel } = props || {}; + const intl = useIntl(); + const handleSelect = (item: { + title: string; + data: { role: string; content: string }[]; + }) => { + props.onSelect(item.data); + onCancel(); + }; + + return ( + +
+ {promptList.map((item, index) => { + return ( +
+

+ {item.title} + +

+ {item.data.map((data, i) => { + return ( +
+ {data.role} + + + {data.content} + + +
+ ); + })} +
+ ); + })} +
+
+ ); +}; + +export default React.memo(AddWorker); diff --git a/src/pages/playground/config/compare-context.ts b/src/pages/playground/config/compare-context.ts new file mode 100644 index 00000000..190f4a89 --- /dev/null +++ b/src/pages/playground/config/compare-context.ts @@ -0,0 +1,20 @@ +import React from 'react'; + +interface CompareContextProps { + spans: { + span: number; + count: number; + }; + systemMessage?: string; + globalParams: Record; + loadingStatus: Record; + handleDeleteModel: (modelname: string) => void; + setSystemMessage?: (message: string) => void; + setGlobalParams: (value: Record) => void; + setLoadingStatus: (modeName: string, status: boolean) => void; +} +const CompareContext = React.createContext( + {} as CompareContextProps +); + +export default CompareContext; diff --git a/src/pages/playground/config/prompt.ts b/src/pages/playground/config/prompt.ts new file mode 100644 index 00000000..20029ff4 --- /dev/null +++ b/src/pages/playground/config/prompt.ts @@ -0,0 +1,57 @@ +import { Roles } from '.'; +export default [ + { + title: 'Grammar correction', + data: [ + { + role: Roles.System, + content: + 'You will be provided with statements, and your task is to convert them to standard English.' + }, + { + role: Roles.User, + content: 'She no went to the market.' + } + ] + }, + { + title: 'Summarize for a 2nd grader', + data: [ + { + role: Roles.System, + content: + 'Summarize content you are provided with for a second-grade student.' + }, + { + role: Roles.User, + content: + 'Jupiter is the fifth planet from the Sun and the largest in the Solar System. It is a gas giant with a mass one-thousandth that of the Sun, but two-and-a-half times that of all the other planets in the Solar System combined. Jupiter is one of the brightest objects visible to the naked eye in the night sky, and has been known to ancient civilizations since before recorded history. It is named after the Roman god Jupiter.[19] When viewed from Earth, Jupiter can be bright enough for its reflected light to cast visible shadows,[20] and is on average the third-brightest natural object in the night sky after the Moon and Venus.' + } + ] + }, + { + title: 'Keywords', + data: [ + { + role: Roles.System, + content: + 'You will be provided with a block of text, and your task is to extract a list of keywords from it.' + }, + { + role: Roles.User, + content: + "Black-on-black ware is a 20th- and 21st-century pottery tradition developed by the Puebloan Native American ceramic artists in Northern New Mexico. Traditional reduction-fired blackware has been made for centuries by pueblo artists. Black-on-black ware of the past century is produced with a smooth surface, with the designs applied through selective burnishing or the application of refractory slip. Another style involves carving or incising designs and selectively polishing the raised areas. For generations several families from Kha'po Owingeh and P'ohwhóge Owingeh pueblos have been making black-on-black ware with the techniques passed down from matriarch potters. Artists from other pueblos have also produced black-on-black ware. Several contemporary artists have created works honoring the pottery of their ancestors." + } + ] + }, + { + title: 'Spreadsheet creator', + data: [ + { + role: Roles.User, + content: + 'Create a two-column CSV of top science fiction movies along with the year of release.' + } + ] + } +]; diff --git a/src/pages/playground/hooks/use-chat-completion.ts b/src/pages/playground/hooks/use-chat-completion.ts index 12490e31..e4176348 100644 --- a/src/pages/playground/hooks/use-chat-completion.ts +++ b/src/pages/playground/hooks/use-chat-completion.ts @@ -10,19 +10,10 @@ interface MessageItemProps { uid: number; } -const useChatCompletion = ( - systemMessage: string, - parameters: Record -) => { +const useChatCompletion = () => { const [loading, setLoading] = useState(false); const messageId = useRef(0); - const [messageList, setMessageList] = useState([ - { - role: 'user', - content: '', - uid: messageId.current - } - ]); + const [messageList, setMessageList] = useState([]); const contentRef = useRef(''); const controllerRef = useRef(null); @@ -53,12 +44,16 @@ const useChatCompletion = ( ]); }; - const submitMessage = async () => { + const submitMessage = async (pramas: { + parameters: Record; + systemMessage: string; + }) => { + const { parameters, systemMessage } = pramas; if (!parameters.model) return; try { setLoading(true); setMessageId(); - + console.log('messagelist=========2=', messageList); controllerRef.current?.abort?.(); controllerRef.current = new AbortController(); const signal = controllerRef.current.signal; diff --git a/src/pages/playground/style/content-item.less b/src/pages/playground/style/content-item.less new file mode 100644 index 00000000..842dd03a --- /dev/null +++ b/src/pages/playground/style/content-item.less @@ -0,0 +1,17 @@ +.content-item { + margin-bottom: 12px; + + &-role { + display: flex; + align-items: center; + font-weight: var(--font-weight-bold); + margin-bottom: 8px; + } + + &-content { + word-break: break-word; + padding: 8px; + border-radius: var(--border-radius-mini); + background-color: var(--ant-color-fill-tertiary); + } +} diff --git a/src/pages/playground/style/multiple-chat.less b/src/pages/playground/style/multiple-chat.less index 5fb7c6c0..a89afee8 100644 --- a/src/pages/playground/style/multiple-chat.less +++ b/src/pages/playground/style/multiple-chat.less @@ -2,7 +2,6 @@ display: flex; flex-direction: column; justify-content: space-between; - height: calc(100vh - 72px); .chat-list { flex: 1; diff --git a/src/pages/playground/style/prompt-modal.less b/src/pages/playground/style/prompt-modal.less new file mode 100644 index 00000000..fe70885e --- /dev/null +++ b/src/pages/playground/style/prompt-modal.less @@ -0,0 +1,46 @@ +.prompt-wrapper { + display: flex; + flex-direction: column; + gap: 16px; + + .title { + display: flex; + align-items: center; + justify-content: space-between; + + .text { + font-weight: var(--font-weight-bold); + } + } + + .prompt-item { + display: flex; + flex-direction: column; + border: 1px solid var(--ant-color-border); + border-radius: var(--border-radius-base); + min-height: 150px; + padding: 10px 12px; + gap: 8px; + + .data-item { + display: flex; + justify-content: flex-start; + align-items: start; + } + + .role { + display: flex; + width: 60px; + flex-basis: 60px; + font-weight: var(--font-weight-bold); + margin-bottom: 8px; + } + + .prompt { + flex: 1; + padding: 8px; + border-radius: var(--border-radius-mini); + background-color: var(--ant-color-fill-tertiary); + } + } +}