fix: chat stream data too long

This commit is contained in:
jialin
2025-11-06 15:37:42 +08:00
parent 38cc179068
commit e1e38f0404
7 changed files with 68 additions and 39 deletions
+6 -8
View File
@@ -1,6 +1,6 @@
import { useIntl } from '@umijs/max';
import _ from 'lodash';
import React, { useCallback, useEffect, useState } from 'react';
import React, { useEffect, useState } from 'react';
import Inner from './inner';
interface LabelSelectorProps {
@@ -45,12 +45,10 @@ const LabelSelector: React.FC<LabelSelectorProps> = ({
}
}, [labels]);
const handleLabelListChange = useCallback(
(list: { key: string; value: string }[]) => {
setLabelList(list);
},
[setLabelList]
);
const handleLabelListChange = (list: { key: string; value: string }[]) => {
setLabelList(list);
};
const handleLabelsChange = (data: Record<string, any>) => {
console.log('handleLabelsChange', data);
setLabelsData(data);
@@ -74,7 +72,7 @@ const LabelSelector: React.FC<LabelSelectorProps> = ({
const [key, value] = line.split('=').map((part) => part.trim());
return { key, value };
});
console.log(lines, parsedData);
console.log('onPaste', lines, parsedData);
setLabelList((prevPairs) => {
const newPairs = [...prevPairs];
+1 -1
View File
@@ -123,4 +123,4 @@ const LabelItem: React.FC<LabelItemProps> = ({
);
};
export default React.memo(LabelItem);
export default LabelItem;
@@ -366,8 +366,6 @@ const AddModal: FC<AddModalProps> = (props) => {
evaluateStateRef.current.state === EvaluateProccess.model &&
item.evaluated
) {
handleShowCompatibleAlert(item.evaluateResult);
const newFormValues = {
...(manual
? { ...defaultFormValues }
@@ -21,9 +21,9 @@ import SearchInput from './search-input';
import SearchResult from './search-result';
const filterOptions = [
{ label: 'FP8', value: 'fp8' },
{ label: 'AWQ', value: 'awq' },
{ label: 'GPTQ', value: 'gptq' },
{ label: 'GGUF', value: 'gguf' }
{ label: 'GPTQ', value: 'gptq' }
];
const PaginationMain = styled(Pagination)`
.ant-pagination-slash {
@@ -541,8 +541,10 @@ const SearchModel: React.FC<SearchInputProps> = (props) => {
onChange={handleFilterChange}
options={filterOptions}
size="middle"
placeholder={intl.formatMessage({ id: 'common.input.type' })}
style={{ width: 120 }}
placeholder={intl.formatMessage({
id: 'models.form.quantization'
})}
style={{ width: 130 }}
></BaseSelect>
</span>
<PaginationMain
+10
View File
@@ -29,3 +29,13 @@ export async function deleteUser(id: number) {
method: 'DELETE'
});
}
export async function updateUserStatus(params: {
id: number;
data: { is_active: boolean };
}) {
return request(`${USERS_API}/${params.id}/activation`, {
method: 'PATCH',
data: params.data
});
}
+18 -2
View File
@@ -23,6 +23,16 @@ const actionList: Global.ActionItem[] = [
key: 'edit',
icon: icons.EditOutlined
},
{
label: 'Active Account',
key: 'active',
icon: icons.EditOutlined
},
{
label: 'Deactivate Account',
key: 'inactive',
icon: icons.EditOutlined
},
{
label: 'common.button.delete',
key: 'delete',
@@ -40,8 +50,14 @@ const useUsersColumns = ({
const setActions = useMemoizedFn((record: ListItem) => {
return actionList.filter((action) => {
if (initialState?.currentUser?.id === record.id) {
return action.key !== 'delete';
if (action.key === 'delete') {
return initialState?.currentUser?.id !== record.id;
}
if (action.key === 'active') {
return !record.is_active && initialState?.currentUser?.id !== record.id;
}
if (action.key === 'inactive') {
return record.is_active && initialState?.currentUser?.id !== record.id;
}
return true;
});
+27 -22
View File
@@ -3,30 +3,33 @@ import qs from 'query-string';
const extractStreamRegx = /(data|error):\s*({.*?})(?=\n|$)/g;
const extractJSON = (dataStr: string) => {
let match;
const extractJSON = (
dataStr: string
): { results: any[]; remaining: string } => {
const results: any[] = [];
if (!dataStr) return { results, remaining: '' };
if (!dataStr) {
return results;
}
while ((match = extractStreamRegx.exec(dataStr)) !== null) {
try {
const type = match[1]; // "data" or "error"
console.log('type========', type);
const jsonData = JSON.parse(match[2]);
if (type === 'error') {
results.push({ error: jsonData });
} else {
results.push(jsonData);
}
} catch (err) {
console.error('JSON parse error:', err, 'for match:', match[2]);
const parts = dataStr.split(/\n\n/);
let remaining = '';
for (let i = 0; i < parts.length; i++) {
const part = parts[i].trim();
if (!part) continue;
if (!part.startsWith('data:') && !part.startsWith('error:')) {
remaining += part;
continue;
}
const jsonStr = part.slice(5).trim();
try {
const parsed = JSON.parse(jsonStr);
results.push(parsed);
} catch {
remaining += part;
}
}
return results;
return { results, remaining };
};
const errorHandler = async (res: any) => {
@@ -181,10 +184,11 @@ export const readStreamData = async (
bufferManager.add({ error: jsonData });
textBuffer = ''; // Clear buffer after processing error
} else {
extractJSON(textBuffer).forEach((data) => {
const { results, remaining } = extractJSON(textBuffer);
results.forEach((data) => {
bufferManager.add(data);
});
textBuffer = ''; // Clear buffer after processing
textBuffer = remaining; // Clear buffer after processing
}
throttledCallback();
@@ -195,10 +199,11 @@ export const readStreamData = async (
if (done) {
textBuffer += decoder.decode();
if (textBuffer) {
extractJSON(textBuffer).forEach((data) => bufferManager.add(data));
const { results, remaining } = extractJSON(textBuffer);
results.forEach((data) => bufferManager.add(data));
}
isReading = false;
bufferManager.flush();
isReading = false;
break;
}
}