mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-06-29 15:31:05 +08:00
fix: restore dataflow defaults and SSE response (#16290)
This commit is contained in:
@@ -123,6 +123,11 @@ export const useSendMessageBySSE = (url: string) => {
|
||||
body: JSON.stringify(body),
|
||||
signal: controller?.signal || sseRef.current?.signal,
|
||||
});
|
||||
const responseDataPromise = response
|
||||
.clone()
|
||||
.json()
|
||||
.then((data: ResponseType) => data)
|
||||
.catch(() => undefined);
|
||||
if (!response.ok) {
|
||||
let errorMessage = response.statusText || 'Request failed';
|
||||
try {
|
||||
@@ -135,8 +140,6 @@ export const useSendMessageBySSE = (url: string) => {
|
||||
} catch {
|
||||
// Non-JSON error body; fall back to the HTTP status text.
|
||||
}
|
||||
setDone(true);
|
||||
resetAnswerList();
|
||||
return {
|
||||
response,
|
||||
data: {
|
||||
@@ -152,76 +155,81 @@ export const useSendMessageBySSE = (url: string) => {
|
||||
?.pipeThrough(new TextDecoderStream())
|
||||
.pipeThrough(new EventSourceParserStream())
|
||||
.getReader();
|
||||
let lastEventData: ResponseType | undefined;
|
||||
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
try {
|
||||
try {
|
||||
// eslint-disable-next-line no-constant-condition
|
||||
while (true) {
|
||||
const x = await reader?.read();
|
||||
if (x) {
|
||||
const { done, value } = x;
|
||||
if (done) {
|
||||
console.info('done');
|
||||
resetAnswerList();
|
||||
break;
|
||||
}
|
||||
try {
|
||||
const raw = (value?.data ?? '').trim();
|
||||
// SSE end-of-stream sentinel — no payload, skip without
|
||||
// surfacing a JSON.parse error to the console.
|
||||
if (!raw) {
|
||||
continue;
|
||||
}
|
||||
// Some upstreams double-wrap the body in a `data:` prefix;
|
||||
// strip one layer so JSON.parse sees a real object.
|
||||
const payload = raw.startsWith('data:')
|
||||
? raw.slice(5).trimStart()
|
||||
: raw;
|
||||
// Check the sentinel after prefix stripping so a
|
||||
// `data: [DONE]` payload is caught and the stream
|
||||
// loop is terminated.
|
||||
if (payload === '[DONE]') {
|
||||
break;
|
||||
}
|
||||
const val = JSON.parse(payload);
|
||||
|
||||
console.info('data:', val);
|
||||
if (typeof val?.code === 'number' && val.code !== 0) {
|
||||
message.error(val.message);
|
||||
}
|
||||
|
||||
setAnswerList((list) => {
|
||||
const nextList = [...list];
|
||||
nextList.push(val);
|
||||
return nextList;
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof DOMException && e.name === 'AbortError') {
|
||||
console.log('Request was aborted by user or logic.');
|
||||
if (!x) {
|
||||
break;
|
||||
}
|
||||
const { done, value } = x;
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
const raw = (value?.data ?? '').trim();
|
||||
// SSE end-of-stream sentinel — no payload, skip without
|
||||
// surfacing a JSON.parse error to the console.
|
||||
if (!raw) {
|
||||
continue;
|
||||
}
|
||||
// Some upstreams double-wrap the body in a `data:` prefix;
|
||||
// strip one layer so JSON.parse sees a real object.
|
||||
const payload = raw.startsWith('data:')
|
||||
? raw.slice(5).trimStart()
|
||||
: raw;
|
||||
// Check the sentinel after prefix stripping so a
|
||||
// `data: [DONE]` payload is caught and the stream
|
||||
// loop is terminated.
|
||||
if (payload === '[DONE]') {
|
||||
break;
|
||||
}
|
||||
const val = JSON.parse(payload);
|
||||
|
||||
if (typeof val?.code === 'number' && val.code !== 0) {
|
||||
message.error(val.message);
|
||||
}
|
||||
lastEventData = val as ResponseType;
|
||||
|
||||
setAnswerList((list) => {
|
||||
const nextList = [...list];
|
||||
nextList.push(val);
|
||||
return nextList;
|
||||
});
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof DOMException && e.name === 'AbortError') {
|
||||
console.log('Request was aborted by user or logic.');
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
console.info('done?');
|
||||
setDone(true);
|
||||
resetAnswerList();
|
||||
|
||||
const responseData = await responseDataPromise;
|
||||
return {
|
||||
response,
|
||||
data: {
|
||||
code: 0,
|
||||
data: true,
|
||||
message: 'success',
|
||||
status: response.status,
|
||||
},
|
||||
data:
|
||||
responseData ??
|
||||
lastEventData ??
|
||||
({
|
||||
code: 0,
|
||||
data: true,
|
||||
message: 'success',
|
||||
status: response.status,
|
||||
} as ResponseType),
|
||||
};
|
||||
} catch (e) {
|
||||
console.warn(e);
|
||||
return undefined;
|
||||
} finally {
|
||||
setDone(true);
|
||||
resetAnswerList();
|
||||
|
||||
console.warn(e);
|
||||
}
|
||||
},
|
||||
[initializeSseRef, url, resetAnswerList],
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
const FILE_ID = 'File';
|
||||
import { FileId, initialParserValues } from '@/pages/agent/constant/pipeline';
|
||||
|
||||
const FILE_OPERATOR = 'File';
|
||||
const INITIAL_PARSER_VALUES = {
|
||||
outputs: {
|
||||
markdown: { type: 'string', value: '' },
|
||||
text: { type: 'string', value: '' },
|
||||
html: { type: 'string', value: '' },
|
||||
json: { type: 'Array<object>', value: [] },
|
||||
},
|
||||
setups: [],
|
||||
};
|
||||
|
||||
// Dataflow seed DSL. Kept separate from UI hooks so pure DSL helpers
|
||||
// can import it without pulling React modules into tests/runtime.
|
||||
@@ -16,7 +8,7 @@ export const DataflowEmptyDsl = {
|
||||
graph: {
|
||||
nodes: [
|
||||
{
|
||||
id: FILE_ID,
|
||||
id: FileId,
|
||||
type: 'beginNode',
|
||||
position: {
|
||||
x: 50,
|
||||
@@ -31,7 +23,7 @@ export const DataflowEmptyDsl = {
|
||||
},
|
||||
{
|
||||
data: {
|
||||
form: INITIAL_PARSER_VALUES,
|
||||
form: initialParserValues,
|
||||
label: 'Parser',
|
||||
name: 'Parser_0',
|
||||
},
|
||||
@@ -54,7 +46,7 @@ export const DataflowEmptyDsl = {
|
||||
edges: [
|
||||
{
|
||||
id: 'xy-edge__Filestart-Parser:HipSignsRhymeend',
|
||||
source: FILE_ID,
|
||||
source: FileId,
|
||||
sourceHandle: 'start',
|
||||
target: 'Parser:HipSignsRhyme',
|
||||
targetHandle: 'end',
|
||||
|
||||
Reference in New Issue
Block a user