浏览代码

Feat: Combine the output logs of the same operator together #3221 (#8638)

### What problem does this PR solve?

Feat: Combine the output logs of the same operator together #3221

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)
tags/v0.20.0
balibabu 4 个月前
父节点
当前提交
747da87a1e
没有帐户链接到提交者的电子邮件
共有 2 个文件被更改,包括 90 次插入6 次删除
  1. 14
    0
      web/src/hooks/use-send-message.ts
  2. 76
    6
      web/src/pages/agent/log-sheet/index.tsx

+ 14
- 0
web/src/hooks/use-send-message.ts 查看文件

MessageEnd = 'message_end', MessageEnd = 'message_end',
WorkflowFinished = 'workflow_finished', WorkflowFinished = 'workflow_finished',
UserInputs = 'user_inputs', UserInputs = 'user_inputs',
NodeLogs = 'node_logs',
} }


export interface IAnswerEvent<T> { export interface IAnswerEvent<T> {
content: string; content: string;
} }


export interface ILogData extends INodeData {
logs: {
name: string;
result: string;
args: {
query: string;
topic: string;
};
};
}

export type INodeEvent = IAnswerEvent<INodeData>; export type INodeEvent = IAnswerEvent<INodeData>;


export type IMessageEvent = IAnswerEvent<IMessageData>; export type IMessageEvent = IAnswerEvent<IMessageData>;


export type IInputEvent = IAnswerEvent<IInputData>; export type IInputEvent = IAnswerEvent<IInputData>;


export type ILogEvent = IAnswerEvent<ILogData>;

export type IChatEvent = INodeEvent | IMessageEvent; export type IChatEvent = INodeEvent | IMessageEvent;


export type IEventList = Array<IChatEvent>; export type IEventList = Array<IChatEvent>;

+ 76
- 6
web/src/pages/agent/log-sheet/index.tsx 查看文件

SheetHeader, SheetHeader,
SheetTitle, SheetTitle,
} from '@/components/ui/sheet'; } from '@/components/ui/sheet';
import { INodeEvent, MessageEventType } from '@/hooks/use-send-message';
import {
ILogData,
ILogEvent,
MessageEventType,
} from '@/hooks/use-send-message';
import { IModalProps } from '@/interfaces/common'; import { IModalProps } from '@/interfaces/common';
import { cn } from '@/lib/utils'; import { cn } from '@/lib/utils';
import { isEmpty } from 'lodash';
import { BellElectric, NotebookText } from 'lucide-react'; import { BellElectric, NotebookText } from 'lucide-react';
import { useCallback, useMemo } from 'react'; import { useCallback, useMemo } from 'react';
import JsonView from 'react18-json-view'; import JsonView from 'react18-json-view';
); );
} }


function concatData(
firstRecord: Record<string, any> | Array<Record<string, any>>,
nextRecord: Record<string, any> | Array<Record<string, any>>,
) {
let result: Array<Record<string, any>> = [];

if (!isEmpty(firstRecord)) {
result = result.concat(firstRecord);
}

if (!isEmpty(nextRecord)) {
result = result.concat(nextRecord);
}

return isEmpty(result) ? {} : result;
}

type EventWithIndex = { startNodeIdx: number } & ILogEvent;

export function LogSheet({ export function LogSheet({
hideModal, hideModal,
currentEventListWithoutMessage, currentEventListWithoutMessage,
[getNode], [getNode],
); );


// Look up to find the nearest start component id and concatenate the finish and log data into one
const finishedNodeList = useMemo(() => { const finishedNodeList = useMemo(() => {
return currentEventListWithoutMessage.filter( return currentEventListWithoutMessage.filter(
(x) => x.event === MessageEventType.NodeFinished,
) as INodeEvent[];
(x) =>
x.event === MessageEventType.NodeFinished ||
x.event === MessageEventType.NodeLogs,
) as ILogEvent[];
}, [currentEventListWithoutMessage]); }, [currentEventListWithoutMessage]);
console.log('🚀 ~ finishedNodeList ~ finishedNodeList:', finishedNodeList);

const nextList = useMemo(() => {
return finishedNodeList.reduce<Array<EventWithIndex>>((pre, cur) => {
const startNodeIdx = (
currentEventListWithoutMessage as Array<ILogEvent>
).findLastIndex(
(x) =>
x.data.component_id === cur.data.component_id &&
x.event === MessageEventType.NodeStarted,
);

const item = pre.find((x) => x.startNodeIdx === startNodeIdx);

const { logs = {}, inputs = {}, outputs = {} } = cur.data;
if (item) {
const {
inputs: inputList,
outputs: outputList,
logs: logList,
} = item.data;

item.data = {
...item.data,
inputs: concatData(inputList, inputs),
outputs: concatData(outputList, outputs),
logs: concatData(logList, logs),
};
} else {
pre.push({
...cur,
startNodeIdx,
});
}

return pre;
}, []);
}, [currentEventListWithoutMessage, finishedNodeList]);


return ( return (
<Sheet open onOpenChange={hideModal} modal={false}> <Sheet open onOpenChange={hideModal} modal={false}>
</SheetHeader> </SheetHeader>
<section className="max-h-[82vh] overflow-auto mt-6"> <section className="max-h-[82vh] overflow-auto mt-6">
<Timeline> <Timeline>
{finishedNodeList.map((x, idx) => (
{nextList.map((x, idx) => (
<TimelineItem <TimelineItem
key={idx} key={idx}
step={idx} step={idx}
title="Input" title="Input"
></JsonViewer> ></JsonViewer>


{isEmpty((x.data as ILogData)?.logs) || (
<JsonViewer
data={(x.data as ILogData)?.logs}
title={'Logs'}
></JsonViewer>
)}

<JsonViewer <JsonViewer
data={x.data.outputs} data={x.data.outputs}
title="Output"
title={'Output'}
></JsonViewer> ></JsonViewer>
</div> </div>
</AccordionContent> </AccordionContent>

正在加载...
取消
保存