refactor: embedding messages format
This commit is contained in:
@@ -11,16 +11,19 @@ import './styles/row-textarea.less';
|
|||||||
interface SystemMessageProps {
|
interface SystemMessageProps {
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
data: {
|
data: {
|
||||||
text: string;
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
uid: number | string;
|
uid: number | string;
|
||||||
name: string;
|
name: string;
|
||||||
dataUrl?: string;
|
role?: string;
|
||||||
};
|
};
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
label?: React.ReactNode;
|
label?: React.ReactNode;
|
||||||
height?: number;
|
height?: number;
|
||||||
onUploadImage?: (list: { uid: number | string; dataUrl: string }[]) => void;
|
onUploadImage?: (list: { uid: number | string; dataUrl: string }[]) => void;
|
||||||
onDeleteImage?: () => void;
|
onDeleteImage?: (
|
||||||
|
updatedImgs: { uid: number | string; dataUrl: string }[]
|
||||||
|
) => void;
|
||||||
onChange: (e: any) => void;
|
onChange: (e: any) => void;
|
||||||
onPaste?: (e: any) => void;
|
onPaste?: (e: any) => void;
|
||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
@@ -90,8 +93,8 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
const start = e.target.selectionStart;
|
const start = e.target.selectionStart;
|
||||||
const end = e.target.selectionEnd;
|
const end = e.target.selectionEnd;
|
||||||
|
|
||||||
const beforeText = data.text.substring(0, start);
|
const beforeText = data.content.substring(0, start);
|
||||||
const afterText = data.text.substring(end, data.text.length);
|
const afterText = data.content.substring(end, data.content.length);
|
||||||
onSelect?.({
|
onSelect?.({
|
||||||
start,
|
start,
|
||||||
end,
|
end,
|
||||||
@@ -116,8 +119,12 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
updateUidCount: () => `img-${Date.now()}`
|
updateUidCount: () => `img-${Date.now()}`
|
||||||
});
|
});
|
||||||
|
|
||||||
const expanded = autoSize.focus || !!data.dataUrl || isFromUrl;
|
const handleDeleteImage = (uid: number) => {
|
||||||
// const expanded = true;
|
const updatedImgs = (data.imgs || []).filter((img) => img.uid !== uid);
|
||||||
|
onDeleteImage?.(updatedImgs);
|
||||||
|
};
|
||||||
|
|
||||||
|
const expanded = autoSize.focus || !!data.imgs?.length || isFromUrl;
|
||||||
|
|
||||||
console.log('expanded===========', expanded);
|
console.log('expanded===========', expanded);
|
||||||
|
|
||||||
@@ -141,14 +148,12 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
className="textarea-wrapper"
|
className="textarea-wrapper"
|
||||||
>
|
>
|
||||||
{label && <span className="textarea-label">{label}</span>}
|
{label && <span className="textarea-label">{label}</span>}
|
||||||
{data.dataUrl && (
|
{!!data.imgs?.length && (
|
||||||
<div style={{ padding: 8 }}>
|
<div style={{ padding: 8 }}>
|
||||||
<ThumbImg
|
<ThumbImg
|
||||||
editable
|
editable
|
||||||
dataList={
|
dataList={data.imgs}
|
||||||
data.dataUrl ? [{ uid: data.uid, dataUrl: data.dataUrl }] : []
|
onDelete={handleDeleteImage}
|
||||||
}
|
|
||||||
onDelete={onDeleteImage}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -164,7 +169,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
width: '100%',
|
width: '100%',
|
||||||
boxShadow: 'none'
|
boxShadow: 'none'
|
||||||
}}
|
}}
|
||||||
value={data.text}
|
value={data.content}
|
||||||
autoSize={
|
autoSize={
|
||||||
expanded
|
expanded
|
||||||
? {
|
? {
|
||||||
@@ -192,7 +197,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
{
|
{
|
||||||
<div className="content" style={{ height: height }}>
|
<div className="content" style={{ height: height }}>
|
||||||
{label && <span className="title">{label}</span>}
|
{label && <span className="title">{label}</span>}
|
||||||
{data.text || (
|
{data.content || (
|
||||||
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
<span style={{ color: 'var(--ant-color-text-tertiary)' }}>
|
||||||
{placeholder}
|
{placeholder}
|
||||||
</span>
|
</span>
|
||||||
@@ -208,7 +213,7 @@ const RowTextarea: React.FC<SystemMessageProps> = (props) => {
|
|||||||
>
|
>
|
||||||
{ImageURLInput}
|
{ImageURLInput}
|
||||||
<div className={'actions'}>
|
<div className={'actions'}>
|
||||||
{!expanded && data.text && (
|
{!expanded && data.content && (
|
||||||
<SmallCloseButton onClick={handleClear}></SmallCloseButton>
|
<SmallCloseButton onClick={handleClear}></SmallCloseButton>
|
||||||
)}
|
)}
|
||||||
{UploadImageButton}
|
{UploadImageButton}
|
||||||
|
|||||||
@@ -58,6 +58,16 @@ export const handleEmbedding = async (
|
|||||||
encoding_format?: string;
|
encoding_format?: string;
|
||||||
dimensions?: number;
|
dimensions?: number;
|
||||||
input: string[];
|
input: string[];
|
||||||
|
messages?: {
|
||||||
|
role: string;
|
||||||
|
content: Array<{
|
||||||
|
type: string;
|
||||||
|
text?: string;
|
||||||
|
image_url?: {
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
}[];
|
||||||
},
|
},
|
||||||
options?: any
|
options?: any
|
||||||
) => {
|
) => {
|
||||||
|
|||||||
@@ -9,25 +9,26 @@ interface InputListProps {
|
|||||||
extra?: (data: any) => React.ReactNode;
|
extra?: (data: any) => React.ReactNode;
|
||||||
showLabel?: boolean;
|
showLabel?: boolean;
|
||||||
textList: {
|
textList: {
|
||||||
text: string;
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
uid: number | string;
|
uid: number | string;
|
||||||
name: string;
|
name: string;
|
||||||
dataUrl?: string;
|
role: string;
|
||||||
}[];
|
}[];
|
||||||
onChange?: (
|
onChange?: (
|
||||||
textList: {
|
textList: {
|
||||||
text: string;
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
uid: number | string;
|
uid: number | string;
|
||||||
name: string;
|
name: string;
|
||||||
dataUrl?: string;
|
role: string;
|
||||||
}[]
|
}[]
|
||||||
) => void;
|
) => void;
|
||||||
onPaste?: (e: any, index: number) => void;
|
onPaste?: (e: any, index: number) => void;
|
||||||
onDeleteImage?: (dataItem: {
|
onDeleteImage?: (
|
||||||
text: string;
|
itemUid: number | string,
|
||||||
uid: number | string;
|
updatedImgs: { uid: number | string; dataUrl: string }[]
|
||||||
name: string;
|
) => void;
|
||||||
}) => void;
|
|
||||||
onUploadImage?: (
|
onUploadImage?: (
|
||||||
list: { uid: number | string; dataUrl: string }[],
|
list: { uid: number | string; dataUrl: string }[],
|
||||||
index: number
|
index: number
|
||||||
@@ -69,14 +70,15 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
setMessageId();
|
setMessageId();
|
||||||
const dataList = [...textList];
|
const dataList = [...textList];
|
||||||
dataList.push({
|
dataList.push({
|
||||||
text: '',
|
content: '',
|
||||||
uid: messageId.current,
|
uid: messageId.current,
|
||||||
name: `Text ${dataList.length + 1}`
|
name: `Text ${dataList.length + 1}`,
|
||||||
|
role: 'user'
|
||||||
});
|
});
|
||||||
onChange?.(dataList);
|
onChange?.(dataList);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDelete = (dataItem: { text: string; uid: number | string }) => {
|
const handleDelete = (dataItem: { uid: number | string }) => {
|
||||||
const dataList = [...textList];
|
const dataList = [...textList];
|
||||||
const index = dataList.findIndex((item) => item.uid === dataItem.uid);
|
const index = dataList.findIndex((item) => item.uid === dataItem.uid);
|
||||||
dataList.splice(index, 1);
|
dataList.splice(index, 1);
|
||||||
@@ -85,11 +87,11 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
|
|
||||||
const handleTextChange = (
|
const handleTextChange = (
|
||||||
value: string,
|
value: string,
|
||||||
dataItem: { text: string; uid: number | string }
|
dataItem: { uid: number | string }
|
||||||
) => {
|
) => {
|
||||||
const dataList = [...textList];
|
const dataList = [...textList];
|
||||||
const index = dataList.findIndex((item) => item.uid === dataItem.uid);
|
const index = dataList.findIndex((item) => item.uid === dataItem.uid);
|
||||||
dataList[index].text = value;
|
dataList[index].content = value;
|
||||||
onChange?.(dataList);
|
onChange?.(dataList);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -117,7 +119,9 @@ const InputList: React.FC<InputListProps> = forwardRef(
|
|||||||
onPaste={(e) => onPaste?.(e, index)}
|
onPaste={(e) => onPaste?.(e, index)}
|
||||||
onSelect={(data) => onSelect?.({ ...data, index })}
|
onSelect={(data) => onSelect?.({ ...data, index })}
|
||||||
onUploadImage={(list) => onUploadImage?.(list, index)}
|
onUploadImage={(list) => onUploadImage?.(list, index)}
|
||||||
onDeleteImage={() => onDeleteImage?.(item)}
|
onDeleteImage={(updatedImgs) =>
|
||||||
|
onDeleteImage?.(item.uid, updatedImgs)
|
||||||
|
}
|
||||||
onDelete={() => handleDelete(item)}
|
onDelete={() => handleDelete(item)}
|
||||||
></RowTextarea>
|
></RowTextarea>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -50,11 +50,21 @@ const normalizeEmbeddingToCanvas = (
|
|||||||
self.onmessage = (
|
self.onmessage = (
|
||||||
event: MessageEvent<{
|
event: MessageEvent<{
|
||||||
embeddings: any[];
|
embeddings: any[];
|
||||||
fileList: { text: string; name: string; uid: number | string }[];
|
fileList: {
|
||||||
textList: { text: string; name: string; uid: number | string }[];
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
name: string;
|
||||||
|
uid: number | string;
|
||||||
|
}[];
|
||||||
|
textList: {
|
||||||
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
name: string;
|
||||||
|
uid: number | string;
|
||||||
|
}[];
|
||||||
}>
|
}>
|
||||||
) => {
|
) => {
|
||||||
const { embeddings, fileList, textList } = event.data;
|
const { embeddings, fileList = [], textList } = event.data;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const dataList = embeddings.map((item) => {
|
const dataList = embeddings.map((item) => {
|
||||||
@@ -71,8 +81,12 @@ self.onmessage = (
|
|||||||
const pcadata = pca.predict(dataList, { nComponents: 2 }).to2DArray();
|
const pcadata = pca.predict(dataList, { nComponents: 2 }).to2DArray();
|
||||||
|
|
||||||
const input = [
|
const input = [
|
||||||
...textList.map((item) => item.text).filter((item) => item),
|
...textList
|
||||||
...fileList.map((item) => item.text).filter((item) => item)
|
.map((item) => item.content || (item.imgs?.length ? `[image]` : ''))
|
||||||
|
.filter((item) => item),
|
||||||
|
...fileList
|
||||||
|
.map((item) => item.content || (item.imgs?.length ? `[image]` : ''))
|
||||||
|
.filter((item) => item)
|
||||||
];
|
];
|
||||||
|
|
||||||
const list = pcadata.map((item: number[], index: number) => {
|
const list = pcadata.map((item: number[], index: number) => {
|
||||||
@@ -83,7 +97,7 @@ self.onmessage = (
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const embeddingJson = embeddings.map((o, index) => {
|
const embeddingJson = embeddings.map((o) => {
|
||||||
const item = _.cloneDeep(o);
|
const item = _.cloneDeep(o);
|
||||||
item.embedding = item.embedding.slice(0, 5);
|
item.embedding = item.embedding.slice(0, 5);
|
||||||
item.embedding.push(null);
|
item.embedding.push(null);
|
||||||
|
|||||||
@@ -49,9 +49,13 @@ export const formatMessageParams = (messageList: any[]) => {
|
|||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generateMessagesByListContent = (messageList: any[]) => {
|
export const generateMessagesByListContent = (
|
||||||
|
messageList: any[],
|
||||||
|
multimodal?: boolean
|
||||||
|
) => {
|
||||||
if (!messageList.length) return [];
|
if (!messageList.length) return [];
|
||||||
return messageList.map((item: MessageItem) => {
|
return messageList.map((item: MessageItem) => {
|
||||||
|
// image
|
||||||
if (item.imgs?.length || item.audio?.length) {
|
if (item.imgs?.length || item.audio?.length) {
|
||||||
const content: any[] = [];
|
const content: any[] = [];
|
||||||
// image
|
// image
|
||||||
@@ -90,7 +94,25 @@ export const generateMessagesByListContent = (messageList: any[]) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return _.omit(item, ['uid', 'imgs', 'audio']);
|
// for multimodal model, if there is text content but no image or audio, also send as multimodal format
|
||||||
|
if (
|
||||||
|
multimodal &&
|
||||||
|
item.content &&
|
||||||
|
!item.imgs?.length &&
|
||||||
|
!item.audio?.length
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
role: item.role,
|
||||||
|
content: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
text: item.content
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return _.omit(item, ['uid', 'imgs', 'audio', 'name']);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,11 @@ import React, {
|
|||||||
useState
|
useState
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import { EMBEDDING_API, handleEmbedding } from '../apis';
|
import { EMBEDDING_API, handleEmbedding } from '../apis';
|
||||||
import FileList from '../components/file-list';
|
|
||||||
import InputList from '../components/input-list';
|
import InputList from '../components/input-list';
|
||||||
import RightContainer from '../components/right-container';
|
import RightContainer from '../components/right-container';
|
||||||
import TokenUsage from '../components/token-usage';
|
import TokenUsage from '../components/token-usage';
|
||||||
import ViewCommonCode from '../components/view-common-code';
|
import ViewCommonCode from '../components/view-common-code';
|
||||||
import { extractErrorMessage } from '../config';
|
import { extractErrorMessage, generateMessagesByListContent } from '../config';
|
||||||
import { embeddingSamples } from '../config/samples';
|
import { embeddingSamples } from '../config/samples';
|
||||||
import { LLM_METAKEYS } from '../hooks/config';
|
import { LLM_METAKEYS } from '../hooks/config';
|
||||||
import useEmbeddingWorker from '../hooks/use-embedding-worker';
|
import useEmbeddingWorker from '../hooks/use-embedding-worker';
|
||||||
@@ -64,9 +63,6 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
const inputListRef = useRef<any>(null);
|
const inputListRef = useRef<any>(null);
|
||||||
const messageListLengthCache = useRef<number>(0);
|
const messageListLengthCache = useRef<number>(0);
|
||||||
const requestToken = useRef<any>(null);
|
const requestToken = useRef<any>(null);
|
||||||
const [fileList, setFileList] = useState<
|
|
||||||
{ text: string; name: string; uid: number | string }[]
|
|
||||||
>([]);
|
|
||||||
const [outputType, setOutputType] = useState<string>('chart');
|
const [outputType, setOutputType] = useState<string>('chart');
|
||||||
const [outputHeight, setOutputHeight] = useState<number>(180);
|
const [outputHeight, setOutputHeight] = useState<number>(180);
|
||||||
const [embeddingData, setEmbeddingData] = useState<{
|
const [embeddingData, setEmbeddingData] = useState<{
|
||||||
@@ -81,19 +77,25 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
const selectionTextRef = useRef<any>(null);
|
const selectionTextRef = useRef<any>(null);
|
||||||
|
|
||||||
const [textList, setTextList] = useState<
|
const [textList, setTextList] = useState<
|
||||||
{ text: string; dataUrl?: string; uid: number | string; name: string }[]
|
{
|
||||||
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
uid: number | string;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
}[]
|
||||||
>([
|
>([
|
||||||
{
|
{
|
||||||
text: '',
|
content: '',
|
||||||
uid: -1,
|
uid: -1,
|
||||||
name: '',
|
name: '',
|
||||||
dataUrl: ''
|
role: 'user'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '',
|
content: '',
|
||||||
uid: -2,
|
uid: -2,
|
||||||
name: '',
|
name: '',
|
||||||
dataUrl: ''
|
role: 'user'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -132,24 +134,47 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const formatInputs = (
|
||||||
|
list: {
|
||||||
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
uid: number | string;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
}[]
|
||||||
|
) => {
|
||||||
|
const validTextList = textList.filter(
|
||||||
|
(item) => item.content || item.imgs?.length
|
||||||
|
);
|
||||||
|
|
||||||
|
const hasImages = validTextList.some((item) => item.imgs?.length);
|
||||||
|
|
||||||
|
const mutipleInput = generateMessagesByListContent(validTextList, true);
|
||||||
|
|
||||||
|
// const firstInput = mutipleInput?.[0];
|
||||||
|
// mutipleInput.forEach((item: any) => {
|
||||||
|
// firstInput.content = firstInput.content.concat(item.content);
|
||||||
|
// });
|
||||||
|
|
||||||
|
return hasImages
|
||||||
|
? { messages: mutipleInput }
|
||||||
|
: { input: [...validTextList.map((item) => item.content || '')] };
|
||||||
|
};
|
||||||
|
|
||||||
const viewCodeContent = useMemo(() => {
|
const viewCodeContent = useMemo(() => {
|
||||||
console.log('viewCodeContent:', embeddingData.copyValue);
|
|
||||||
return generateEmbeddingCode({
|
return generateEmbeddingCode({
|
||||||
api: EMBEDDING_API,
|
api: EMBEDDING_API,
|
||||||
parameters: {
|
parameters: {
|
||||||
...parameters,
|
...parameters,
|
||||||
input: [
|
...formatInputs(textList)
|
||||||
...textList.map((item) => item.text).filter((item) => item),
|
|
||||||
...fileList.map((item) => item.text).filter((item) => item)
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, [parameters, textList, fileList]);
|
}, [parameters, textList]);
|
||||||
|
|
||||||
const inputEmpty = useMemo(() => {
|
const inputEmpty = useMemo(() => {
|
||||||
const list = [...textList, ...fileList];
|
const list = [...textList];
|
||||||
return list.length < 2;
|
return list.length < 2;
|
||||||
}, [textList, fileList]);
|
}, [textList]);
|
||||||
|
|
||||||
const setMessageId = () => {
|
const setMessageId = () => {
|
||||||
return inputListRef.current?.setMessageId?.();
|
return inputListRef.current?.setMessageId?.();
|
||||||
@@ -165,23 +190,18 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
await formRef.current?.form.validateFields();
|
await formRef.current?.form.validateFields();
|
||||||
if (!parameters.model) return;
|
if (!parameters.model) return;
|
||||||
const validTextList = textList.filter(
|
const validTextList = textList.filter(
|
||||||
(item) => item.text || item.dataUrl
|
(item) => item.content || item.imgs?.length
|
||||||
);
|
);
|
||||||
const validFileList = fileList.filter((item) => item.text);
|
|
||||||
|
|
||||||
const inputList = [
|
const inputList = formatInputs(textList);
|
||||||
...validTextList.map((item) => item.text || item.dataUrl || ''),
|
|
||||||
...validFileList.map((item) => item.text || '')
|
|
||||||
];
|
|
||||||
|
|
||||||
if (inputList.length < 2) {
|
if (validTextList.length < 2) {
|
||||||
setLessTwoInput(true);
|
setLessTwoInput(true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setTextList(validTextList);
|
setTextList(validTextList);
|
||||||
setFileList(validFileList);
|
|
||||||
|
|
||||||
setLessTwoInput(false);
|
setLessTwoInput(false);
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
@@ -197,7 +217,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
{
|
{
|
||||||
model: parameters.model,
|
model: parameters.model,
|
||||||
encoding_format: 'float',
|
encoding_format: 'float',
|
||||||
input: inputList
|
...inputList
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
token: requestToken.current.token
|
token: requestToken.current.token
|
||||||
@@ -220,8 +240,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
|
|
||||||
postMessage({
|
postMessage({
|
||||||
embeddings: embeddingsList,
|
embeddings: embeddingsList,
|
||||||
textList: textList,
|
textList: textList
|
||||||
fileList: fileList
|
|
||||||
});
|
});
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
setTokenResult({
|
setTokenResult({
|
||||||
@@ -262,17 +281,18 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteFile = (uid: number | string) => {
|
|
||||||
setFileList((preList) => {
|
|
||||||
return preList.filter((item) => item.uid !== uid);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
const handleAddText = () => {
|
const handleAddText = () => {
|
||||||
inputListRef.current?.handleAdd();
|
inputListRef.current?.handleAdd();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleTextListChange = (
|
const handleTextListChange = (
|
||||||
list: { text: string; uid: number | string; name: string }[]
|
list: {
|
||||||
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
uid: number | string;
|
||||||
|
name: string;
|
||||||
|
role: string;
|
||||||
|
}[]
|
||||||
) => {
|
) => {
|
||||||
setTextList(list);
|
setTextList(list);
|
||||||
};
|
};
|
||||||
@@ -281,35 +301,29 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
list: { uid: number | string; dataUrl: string }[],
|
list: { uid: number | string; dataUrl: string }[],
|
||||||
index: number
|
index: number
|
||||||
) => {
|
) => {
|
||||||
// replace the text with dataUrl in the textList
|
|
||||||
setTextList((preList) => {
|
setTextList((preList) => {
|
||||||
const newList = [...preList];
|
const newList = [...preList];
|
||||||
const current = newList[index];
|
const current = newList[index];
|
||||||
if (current) {
|
if (current) {
|
||||||
newList[index] = {
|
newList[index] = {
|
||||||
...current,
|
...current,
|
||||||
text: '',
|
content: '',
|
||||||
uid: list[0].uid,
|
imgs: list
|
||||||
dataUrl: list[0].dataUrl
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return newList;
|
return newList;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleOnDeleteImage = (item: {
|
const handleOnDeleteImage = (
|
||||||
text: string;
|
itemUid: number | string,
|
||||||
uid: number | string;
|
updatedImgs: { uid: number | string; dataUrl: string }[]
|
||||||
name: string;
|
) => {
|
||||||
dataUrl?: string;
|
|
||||||
}) => {
|
|
||||||
// replace the dataUrl with empty text in the textList
|
|
||||||
setTextList((preList) => {
|
setTextList((preList) => {
|
||||||
const newList = [...preList];
|
const newList = [...preList];
|
||||||
const current = newList.find((i) => i.uid === item.uid);
|
const current = newList.find((i) => i.uid === itemUid);
|
||||||
if (current) {
|
if (current) {
|
||||||
current.text = '';
|
current.imgs = updatedImgs;
|
||||||
current.dataUrl = '';
|
|
||||||
}
|
}
|
||||||
return newList;
|
return newList;
|
||||||
});
|
});
|
||||||
@@ -335,17 +349,18 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
if (text) {
|
if (text) {
|
||||||
const dataLlist = text.split('\n').map((item: string) => {
|
const dataLlist = text.split('\n').map((item: string) => {
|
||||||
return {
|
return {
|
||||||
text: item?.trim(),
|
content: item?.trim(),
|
||||||
name: '',
|
name: '',
|
||||||
uid: setMessageId()
|
uid: setMessageId(),
|
||||||
|
role: 'user'
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
dataLlist[0].text = `${selectionTextRef.current?.beforeText || ''}${dataLlist[0].text}${selectionTextRef.current?.afterText || ''}`;
|
dataLlist[0].content = `${selectionTextRef.current?.beforeText || ''}${dataLlist[0].content}${selectionTextRef.current?.afterText || ''}`;
|
||||||
const result = [
|
const result = [
|
||||||
...textList.slice(0, index),
|
...textList.slice(0, index),
|
||||||
...dataLlist,
|
...dataLlist,
|
||||||
...textList.slice(index + 1)
|
...textList.slice(index + 1)
|
||||||
].filter((item) => item.text);
|
].filter((item) => item.content || item.imgs?.length);
|
||||||
|
|
||||||
setTextList(result);
|
setTextList(result);
|
||||||
}
|
}
|
||||||
@@ -356,17 +371,18 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
const handleClearDocuments = () => {
|
const handleClearDocuments = () => {
|
||||||
setTextList([
|
setTextList([
|
||||||
{
|
{
|
||||||
text: '',
|
content: '',
|
||||||
uid: -1,
|
uid: -1,
|
||||||
name: ''
|
name: '',
|
||||||
|
role: 'user'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '',
|
content: '',
|
||||||
uid: -2,
|
uid: -2,
|
||||||
name: ''
|
name: '',
|
||||||
|
role: 'user'
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
setFileList([]);
|
|
||||||
setScatterData([]);
|
setScatterData([]);
|
||||||
setTokenResult(null);
|
setTokenResult(null);
|
||||||
setLessTwoInput(false);
|
setLessTwoInput(false);
|
||||||
@@ -452,11 +468,11 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
}, [initialize]);
|
}, [initialize]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (textList.length + fileList.length > messageListLengthCache.current) {
|
if (textList.length > messageListLengthCache.current) {
|
||||||
updateDocumentScrollerPosition();
|
updateDocumentScrollerPosition();
|
||||||
}
|
}
|
||||||
messageListLengthCache.current = textList.length + fileList.length;
|
messageListLengthCache.current = textList.length;
|
||||||
}, [textList.length, fileList.length]);
|
}, [textList.length]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (intl.locale || 'en-US') {
|
if (intl.locale || 'en-US') {
|
||||||
@@ -465,9 +481,10 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
if (sample) {
|
if (sample) {
|
||||||
setTextList(
|
setTextList(
|
||||||
sample.map((item: string, index: number) => ({
|
sample.map((item: string, index: number) => ({
|
||||||
text: item,
|
content: item,
|
||||||
uid: setMessageId(),
|
uid: setMessageId(),
|
||||||
name: `Document ${index + 1}`
|
name: `Document ${index + 1}`,
|
||||||
|
role: 'user'
|
||||||
}))
|
}))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -577,15 +594,6 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
onUploadImage={handleOnUploadImage}
|
onUploadImage={handleOnUploadImage}
|
||||||
onDeleteImage={handleOnDeleteImage}
|
onDeleteImage={handleOnDeleteImage}
|
||||||
></InputList>
|
></InputList>
|
||||||
{fileList.length > 0 && (
|
|
||||||
<div style={{ marginTop: 8 }}>
|
|
||||||
<FileList
|
|
||||||
fileList={fileList}
|
|
||||||
textListCount={textList.length || 0}
|
|
||||||
onDelete={handleDeleteFile}
|
|
||||||
></FileList>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{lessTwoInput && (
|
{lessTwoInput && (
|
||||||
<div className="m-t-16">
|
<div className="m-t-16">
|
||||||
<AlertInfo
|
<AlertInfo
|
||||||
@@ -645,6 +653,7 @@ const GroundEmbedding: React.FC<MessageProps> = forwardRef((props, ref) => {
|
|||||||
<Segmented
|
<Segmented
|
||||||
onChange={handleOutputTypeChange}
|
onChange={handleOutputTypeChange}
|
||||||
value={outputType}
|
value={outputType}
|
||||||
|
size="middle"
|
||||||
options={[
|
options={[
|
||||||
{
|
{
|
||||||
label: intl.formatMessage({
|
label: intl.formatMessage({
|
||||||
|
|||||||
@@ -17,8 +17,18 @@ export default function useEmbeddingWorker() {
|
|||||||
|
|
||||||
const postMessage = (params: {
|
const postMessage = (params: {
|
||||||
embeddings: any[];
|
embeddings: any[];
|
||||||
textList: { text: string; name: string; uid: number | string }[];
|
textList: {
|
||||||
fileList: { text: string; name: string; uid: number | string }[];
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
name: string;
|
||||||
|
uid: number | string;
|
||||||
|
}[];
|
||||||
|
fileList?: {
|
||||||
|
content: string;
|
||||||
|
imgs?: { uid: number | string; dataUrl: string }[];
|
||||||
|
name: string;
|
||||||
|
uid: number | string;
|
||||||
|
}[];
|
||||||
}) => {
|
}) => {
|
||||||
if (workerRef.current) {
|
if (workerRef.current) {
|
||||||
workerRef.current.postMessage(params);
|
workerRef.current.postMessage(params);
|
||||||
|
|||||||
Reference in New Issue
Block a user