refactor: playground rerank layout

This commit is contained in:
jialin
2024-11-22 10:00:34 +08:00
parent 8e7fa486db
commit 1e3957bdd5
12 changed files with 218 additions and 135 deletions
+8
View File
@@ -132,6 +132,10 @@
gap: 8px;
}
.gap-20 {
gap: 20px;
}
.line-24 {
line-height: 24px;
}
@@ -160,6 +164,10 @@
font-size: 20px;
}
.m-b-0 {
margin-bottom: 0;
}
.font-400 {
font-weight: var(--font-weight-normal);
}
@@ -34,8 +34,7 @@
.textarea-label {
position: relative;
top: 1px;
font-weight: var(--font-weight-bold);
top: 4px;
padding-left: 14px;
}
+3 -1
View File
@@ -294,7 +294,9 @@ export default (props: any) => {
}
}}
formatMessage={formatMessage}
menu={{ locale: true }}
menu={{
locale: true
}}
logo={collapsed ? SLogoIcon : LogoIcon}
menuItemRender={(menuItemProps, defaultDom) => {
if (menuItemProps.isUrl || menuItemProps.children) {
+3
View File
@@ -108,7 +108,10 @@ export const getRightRenderContent = (opts: {
: 'user-menu-container',
mode: 'vertical',
expandIcon: false,
<<<<<<< HEAD
// inlineCollapsed: collapsed,
=======
>>>>>>> 7174170 (refactor: playground rerank layout)
triggerSubMenuAction: 'hover',
items: [
{
@@ -1,14 +1,10 @@
import useOverlayScroller from '@/hooks/use-overlay-scroller';
import useRequestToken from '@/hooks/use-request-token';
import {
ClearOutlined,
PlusOutlined,
SearchOutlined,
UploadOutlined
} from '@ant-design/icons';
import { ClearOutlined, PlusOutlined, SearchOutlined } from '@ant-design/icons';
import { useIntl, useSearchParams } from '@umijs/max';
import { Button, Divider, Spin, Tooltip } from 'antd';
import { Button, Spin } from 'antd';
import classNames from 'classnames';
import _ from 'lodash';
import 'overlayscrollbars/overlayscrollbars.css';
import {
forwardRef,
@@ -23,13 +19,11 @@ import { MessageItem } from '../config/types';
import '../style/ground-left.less';
import '../style/rerank.less';
import '../style/system-message-wrap.less';
import FileList from './file-list';
import InputList from './input-list';
import MessageInput from './message-input';
import ReferenceParams from './reference-params';
import RerankMessage from './rerank-message';
import RerankerParams from './reranker-params';
import UploadFile from './upload-file';
import ViewRerankCode from './view-rerank-code';
interface MessageProps {
@@ -68,7 +62,18 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
const [textList, setTextList] = useState<
{ text: string; uid: number | string; name: string }[]
>([]);
>([
{
text: '',
uid: -1,
name: ''
},
{
text: '',
uid: -2,
name: ''
}
]);
const { initialize, updateScrollerPosition } = useOverlayScroller();
const {
@@ -128,6 +133,11 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
setMessageId();
setTokenResult(result.usage);
const maxItem = _.maxBy(result.results || [], (item: any) =>
Math.abs(item.relevance_score)
);
const maxValue = _.ceil(maxItem?.relevance_score, 2);
setMessageList([
{
title: 'Results',
@@ -135,10 +145,12 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
content: result.results?.map((item: any) => {
return {
uid: item.index,
text: `${item.document?.text?.slice(0, 500) || ''}`,
text: `${item.document?.slice(0, 500) || ''}`,
docIndex: item.index,
title: documentList[item.index]?.name || '',
score: item.relevance_score
score: item.relevance_score,
normalizValue:
_.round(_.round(item.relevance_score, 2) / maxValue, 2) * 100
};
}),
uid: messageId.current
@@ -195,7 +207,18 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
};
const handleClearDocuments = () => {
setTextList([]);
setTextList([
{
text: '',
uid: -1,
name: ''
},
{
text: '',
uid: -2,
name: ''
}
]);
setFileList([]);
};
@@ -231,86 +254,6 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
return (
<div className="ground-left-wrapper rerank">
<div className="ground-left">
<div className="center">
<div className="documents">
<h3 className="m-b-20 m-l-10 flex-between flex-center font-size-14 line-24">
<span>Documents</span>
</h3>
<div className="flex-between m-b-8 p-l-8">
<div className="flex gap-10">
<UploadFile
handleUpdateFileList={handleUpdateFileList}
accept={acceptType}
>
<Tooltip title={<span>Support: {acceptType}</span>}>
<Button
size="middle"
icon={<UploadOutlined></UploadOutlined>}
>
Upload File
</Button>
</Tooltip>
</UploadFile>
<Button size="middle" onClick={handleAddText}>
<PlusOutlined />
Add Text
</Button>
</div>
<Button
type="text"
icon={<ClearOutlined />}
size="middle"
onClick={handleClearDocuments}
></Button>
</div>
<div className="docs-wrapper">
<InputList
ref={inputListRef}
textList={textList}
onChange={handleTextListChange}
></InputList>
<div style={{ marginTop: 8 }}>
<FileList
fileList={fileList}
textListCount={textList.length || 0}
onDelete={handleDeleteFile}
></FileList>
</div>
</div>
</div>
<Divider
type="vertical"
style={{ margin: 0, height: '100%' }}
></Divider>
<div
className="message-list-wrap"
ref={scroller}
style={{ paddingInline: 16 }}
>
<>
<div className="content">
<RerankMessage
dataList={messageList}
header={
<div className="result-header">
<span className="title">Results</span>
<ReferenceParams
usage={tokenResult}
showOutput={false}
></ReferenceParams>
</div>
}
/>
{loading && (
<Spin size="small">
<div style={{ height: '46px' }}></div>
</Spin>
)}
</div>
</>
</div>
</div>
<div className="ground-left-footer">
<MessageInput
scope="reranker"
@@ -326,9 +269,92 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
placeholer={intl.formatMessage({
id: 'playground.input.keyword.holder'
})}
tools={<span className="p-l-8">Query</span>}
tools={<span style={{ paddingLeft: 6 }}>Query</span>}
style={{
borderTop: 'none',
width: 'unset',
marginInline: 32,
marginTop: 16,
border: '1px solid var(--ant-color-border)',
borderRadius: 'var(--border-radius-base)',
paddingInline: 10
}}
/>
</div>
<div className="center" ref={scroller}>
<div className="documents">
<div className="flex-between m-b-8 doc-header">
<h3 className="m-l-10 flex-between flex-center font-size-14 line-24 m-b-0">
<span>Documents</span>
</h3>
<div className="flex gap-20">
{/* <UploadFile
handleUpdateFileList={handleUpdateFileList}
accept={acceptType}
>
<Tooltip title={<span>Support: {acceptType}</span>}>
<Button
size="middle"
icon={<UploadOutlined></UploadOutlined>}
>
Upload File
</Button>
</Tooltip>
</UploadFile> */}
<Button size="middle" onClick={handleAddText}>
<PlusOutlined />
Add Text
</Button>
<Button
type="text"
icon={<ClearOutlined />}
size="middle"
onClick={handleClearDocuments}
></Button>
</div>
</div>
<div className="docs-wrapper">
<InputList
ref={inputListRef}
textList={textList}
onChange={handleTextListChange}
></InputList>
{/* <div style={{ marginTop: 8 }}>
<FileList
fileList={fileList}
textListCount={textList.length || 0}
onDelete={handleDeleteFile}
></FileList>
</div> */}
</div>
</div>
<div>
{messageList.length ? (
<div className="result-header flex-center">
<h3 className="font-size-14 m-b-0">Results</h3>
<ReferenceParams
usage={tokenResult}
showOutput={false}
></ReferenceParams>
</div>
) : null}
</div>
<div
className="message-list-wrap"
style={{ paddingInline: 0, paddingTop: 0 }}
>
<>
<div className="content">
<RerankMessage dataList={messageList} />
{loading && (
<Spin size="small">
<div style={{ height: '46px' }}></div>
</Spin>
)}
</div>
</>
</div>
</div>
</div>
<div
className={classNames('params-wrapper', {
@@ -336,7 +362,7 @@ const GroundReranker: React.FC<MessageProps> = forwardRef((props, ref) => {
})}
ref={paramsRef}
>
<div className="box" style={{ padding: collapse ? 0 : '0 16px' }}>
<div className="box">
<RerankerParams
setParams={setParams}
params={parameters}
@@ -58,17 +58,6 @@ const InputList: React.FC<InputListProps> = forwardRef(
return (
<div className="input-list">
{/* {textList.length === 0 && (
<Button
block
onClick={handleAdd}
type="text"
style={{ backgroundColor: 'var(--ant-color-fill-secondary)' }}
>
<PlusOutlined />
Add Text
</Button>
)} */}
{textList.map((text, index) => {
return (
<div key={text.uid} className="input-item">
@@ -92,18 +81,6 @@ const InputList: React.FC<InputListProps> = forwardRef(
onClick={() => handleDelete(text)}
></Button>
</Tooltip>
{/* {index === textList.length - 1 && (
<Tooltip
title={intl.formatMessage({ id: 'common.button.add' })}
>
<Button
size="small"
type="text"
icon={<PlusCircleOutlined />}
onClick={handleAdd}
></Button>
</Tooltip>
)} */}
</span>
</div>
);
@@ -76,6 +76,7 @@ interface MessageInputProps {
scope: string;
placeholer?: string;
shouldResetMessage?: boolean;
style?: React.CSSProperties;
}
const MessageInput: React.FC<MessageInputProps> = ({
@@ -95,7 +96,7 @@ const MessageInput: React.FC<MessageInputProps> = ({
submitIcon,
placeholer,
tools,
style,
shouldResetMessage = true
}) => {
const { TextArea } = Input;
@@ -347,7 +348,7 @@ const MessageInput: React.FC<MessageInputProps> = ({
);
return (
<div className="messageInput">
<div className="messageInput" style={{ ...style }}>
<div className="tool-bar">
<div className="actions">
{tools}
@@ -1,4 +1,4 @@
import { Tooltip } from 'antd';
import { Progress, Tooltip } from 'antd';
import _ from 'lodash';
import React from 'react';
import '../style/content-item.less';
@@ -18,9 +18,6 @@ const RerankMessage: React.FC<RerankMessageProps> = ({ header, dataList }) => {
{dataList.map((item) => {
return (
<div className="content-item" key={item.uid}>
{/* <div className="content-item-role">
<span className="role">{item.title}</span>
</div> */}
<div className="content-item-content">
{Array.isArray(item.content) ? (
<div className="result">
@@ -37,6 +34,33 @@ const RerankMessage: React.FC<RerankMessageProps> = ({ header, dataList }) => {
>
<dd className="text">{sItem.text}</dd>
</Tooltip>
<Progress
format={() => (
<span
style={{
paddingRight: 4,
color: 'var(--ant-color-text-tertiary)'
}}
>
{_.round(sItem.score, 2)}
</span>
)}
size={{
height: 4
}}
type="line"
status="normal"
percentPosition={{ align: 'end', type: 'outer' }}
strokeColor="rgb(22 119 255 / 27%)"
trailColor="transparent"
percent={sItem.normalizValue}
style={{
position: 'absolute',
left: 0,
bottom: 0,
lineHeight: '12px'
}}
></Progress>
</dl>
);
})}
@@ -43,7 +43,7 @@ const ViewCodeModal: React.FC<ViewModalProps> = (props) => {
const generateCode = () => {
if (lang === langMap.shell) {
const code = `curl ${window.location.origin}/v1-openai \\\n-H "Content-Type: application/json" \\\n-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\\n-d '${JSON.stringify(
const code = `curl ${window.location.origin}/v1/rerank \\\n-H "Content-Type: application/json" \\\n-H "Authorization: Bearer $\{YOUR_GPUSTACK_API_KEY}" \\\n-d '${JSON.stringify(
{
...parameters,
documents: documentList
+9 -2
View File
@@ -1,7 +1,7 @@
.input-list {
display: flex;
flex-direction: column;
gap: 8px;
gap: 12px;
.input-item {
display: flex;
@@ -11,7 +11,14 @@
padding-right: 6px;
cursor: pointer;
transition: background-color 0.3s ease;
border-bottom: 1px solid var(--ant-color-split);
border-radius: var(--border-radius-base);
border: 1px solid var(--ant-color-border);
// &:focus-within {
// border-color: var(--ant-input-active-border-color);
// box-shadow: var(--ant-input-active-shadow);
// outline: 0;
// background-color: var(--ant-input-active-bg);
// }
.btn-group {
display: none;
+10 -2
View File
@@ -53,8 +53,11 @@
}
.content-item-content {
position: relative;
padding: 14px;
padding-left: 8px;
border-radius: 0 0 var(--border-radius-base) var(--border-radius-base);
background-color: transparent;
}
.result-header {
@@ -62,9 +65,14 @@
align-items: center;
justify-content: space-between;
border-radius: 4px 4px 0 0;
background: var(--ant-color-fill-tertiary);
padding: 0 14px;
min-height: 41px;
padding: 0 10px;
border-bottom: 1px solid var(--ant-color-split);
padding-left: 10px;
position: sticky;
top: 0;
background: #fff;
z-index: 100;
.title {
font-weight: var(--font-weight-medium);
+31 -3
View File
@@ -1,16 +1,44 @@
.ground-left-wrapper.rerank {
.center {
display: flex;
flex-direction: column;
height: 100%;
padding-inline: 32px;
padding-bottom: 16px;
.documents {
width: 390px;
padding: 16px;
padding-left: 32px;
width: 100%;
.doc-header {
margin-bottom: 16px;
padding-top: 16px;
position: sticky;
top: 0;
background: var(--color-white-1);
z-index: 100;
}
}
.message-list-wrap {
flex: 1;
}
.result-header {
display: flex;
align-items: center;
justify-content: space-between;
border-radius: 4px 4px 0 0;
min-height: 41px;
padding: 0 10px;
margin-top: 16px;
position: sticky;
top: 0;
background: var(--color-white-1);
z-index: 100;
.title {
font-weight: var(--font-weight-medium);
}
}
}
}