diff --git a/web/src/hooks/logic-hooks.ts b/web/src/hooks/logic-hooks.ts index c0a353579..73af17e6b 100644 --- a/web/src/hooks/logic-hooks.ts +++ b/web/src/hooks/logic-hooks.ts @@ -334,6 +334,20 @@ export const useSelectDerivedMessages = () => { [], ); + const addNewestOneQuestion = useCallback((message: Message) => { + setDerivedMessages((pre) => { + return [ + ...pre, + { + ...message, + id: buildMessageUuid(message), // The message id is generated on the front end, + // and the message id returned by the back end is the same as the question id, + // so that the pair of messages can be deleted together when deleting the message + }, + ]; + }); + }, []); + // Add the streaming message to the last item in the message list const addNewestAnswer = useCallback((answer: IAnswer) => { setDerivedMessages((pre) => { @@ -355,6 +369,38 @@ export const useSelectDerivedMessages = () => { }); }, []); + // Add the streaming message to the last item in the message list + const addNewestOneAnswer = useCallback((answer: IAnswer) => { + setDerivedMessages((pre) => { + const idx = pre.findIndex((x) => x.id === answer.id); + + if (idx !== -1) { + return pre.map((x) => { + if (x.id === answer.id) { + return { ...x, content: answer.answer }; + } + return x; + }); + } + + return [ + ...(pre ?? []), + { + role: MessageType.Assistant, + content: answer.answer, + reference: answer.reference, + id: buildMessageUuid({ + id: answer.id, + role: MessageType.Assistant, + }), + prompt: answer.prompt, + audio_binary: answer.audio_binary, + ...omit(answer, 'reference'), + }, + ]; + }); + }, []); + const removeLatestMessage = useCallback(() => { setDerivedMessages((pre) => { const nextMessages = pre?.slice(0, -2) ?? []; @@ -406,6 +452,8 @@ export const useSelectDerivedMessages = () => { addNewestAnswer, removeLatestMessage, removeMessageById, + addNewestOneQuestion, + addNewestOneAnswer, removeMessagesAfterCurrentMessage, }; }; diff --git a/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx b/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx index 99f33471a..3a18233a1 100644 --- a/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx +++ b/web/src/pages/agent/canvas/node/dropdown/next-step-dropdown.tsx @@ -93,7 +93,9 @@ function AccordionOperators() { Tools - + diff --git a/web/src/pages/agent/chat/hooks.ts b/web/src/pages/agent/chat/hooks.ts index e813c90c4..d9e220cc0 100644 --- a/web/src/pages/agent/chat/hooks.ts +++ b/web/src/pages/agent/chat/hooks.ts @@ -37,6 +37,8 @@ export const useSelectNextMessages = () => { removeLatestMessage, removeMessageById, removeMessagesAfterCurrentMessage, + addNewestOneQuestion, + addNewestOneAnswer, } = useSelectDerivedMessages(); return { @@ -48,6 +50,8 @@ export const useSelectNextMessages = () => { addNewestAnswer, removeLatestMessage, removeMessageById, + addNewestOneQuestion, + addNewestOneAnswer, removeMessagesAfterCurrentMessage, }; }; @@ -57,7 +61,7 @@ function findMessageFromList(eventList: IEventList) { (x) => x.event === MessageEventType.Message, ) as IMessageEvent[]; return { - id: messageEventList[0]?.message_id, + id: eventList[0]?.message_id, content: messageEventList.map((x) => x.data.content).join(''), }; } @@ -83,6 +87,8 @@ export const useSendNextMessage = () => { addNewestAnswer, removeLatestMessage, removeMessageById, + addNewestOneQuestion, + addNewestOneAnswer, } = useSelectNextMessages(); const { id: agentId } = useParams(); const { handleInputChange, value, setValue } = useHandleMessageInputChange(); @@ -132,13 +138,13 @@ export const useSendNextMessage = () => { useEffect(() => { const { content, id } = findMessageFromList(answerList); - if (content) { - addNewestAnswer({ + if (answerList.length > 0) { + addNewestOneAnswer({ answer: content, id: id, }); } - }, [answerList, addNewestAnswer]); + }, [answerList, addNewestOneAnswer]); const handlePressEnter = useCallback(() => { if (trim(value) === '') return; @@ -147,20 +153,20 @@ export const useSendNextMessage = () => { setValue(''); handleSendMessage({ id, content: value.trim(), role: MessageType.User }); } - addNewestQuestion({ + addNewestOneQuestion({ content: value, id, role: MessageType.User, }); - }, [addNewestQuestion, handleSendMessage, done, setValue, value]); + }, [value, done, addNewestOneQuestion, setValue, handleSendMessage]); useEffect(() => { if (prologue) { - addNewestAnswer({ + addNewestOneAnswer({ answer: prologue, }); } - }, [addNewestAnswer, prologue]); + }, [addNewestOneAnswer, prologue]); useEffect(() => { addEventList(answerList); diff --git a/web/src/pages/agent/constant.tsx b/web/src/pages/agent/constant.tsx index cebd46240..f590d7a58 100644 --- a/web/src/pages/agent/constant.tsx +++ b/web/src/pages/agent/constant.tsx @@ -85,7 +85,7 @@ export enum Operator { WaitingDialogue = 'WaitingDialogue', Agent = 'Agent', Tool = 'Tool', - Tavily = 'Tavily', + TavilySearch = 'TavilySearch', } export const SwitchLogicOperatorOptions = ['and', 'or']; @@ -250,7 +250,7 @@ export const operatorMap: Record< [Operator.Code]: { backgroundColor: '#4c5458' }, [Operator.WaitingDialogue]: { backgroundColor: '#a5d65c' }, [Operator.Agent]: { backgroundColor: '#a5d65c' }, - [Operator.Tavily]: { backgroundColor: '#a5d65c' }, + [Operator.TavilySearch]: { backgroundColor: '#a5d65c' }, }; export const componentMenuList = [ @@ -805,6 +805,7 @@ export const RestrictedUpstreamMap = { [Operator.Code]: [Operator.Begin], [Operator.WaitingDialogue]: [Operator.Begin], [Operator.Agent]: [Operator.Begin], + [Operator.TavilySearch]: [Operator.Begin], }; export const NodeMap = { @@ -848,7 +849,7 @@ export const NodeMap = { [Operator.WaitingDialogue]: 'ragNode', [Operator.Agent]: 'agentNode', [Operator.Tool]: 'toolNode', - [Operator.Tavily]: 'ragNode', + [Operator.TavilySearch]: 'ragNode', }; export const LanguageOptions = [ diff --git a/web/src/pages/agent/form-sheet/next.tsx b/web/src/pages/agent/form-sheet/next.tsx index fb500458e..8bfd9d2af 100644 --- a/web/src/pages/agent/form-sheet/next.tsx +++ b/web/src/pages/agent/form-sheet/next.tsx @@ -43,7 +43,7 @@ const FormSheet = ({ const currentFormMap = FormConfigMap[operatorName]; - const OperatorForm = currentFormMap.component ?? EmptyContent; + const OperatorForm = currentFormMap?.component ?? EmptyContent; const { name, handleNameBlur, handleNameChange } = useHandleNodeNameChange({ id: node?.id, diff --git a/web/src/pages/agent/form-sheet/use-form-config-map.tsx b/web/src/pages/agent/form-sheet/use-form-config-map.tsx index 50b537a07..267682a1a 100644 --- a/web/src/pages/agent/form-sheet/use-form-config-map.tsx +++ b/web/src/pages/agent/form-sheet/use-form-config-map.tsx @@ -376,7 +376,7 @@ export function useFormConfigMap() { defaultValues: {}, schema: z.object({}), }, - [Operator.Tavily]: { + [Operator.TavilySearch]: { component: TavilyForm, defaultValues: {}, schema: z.object({}), diff --git a/web/src/pages/agent/form/agent-form/tool-popover/tool-command.tsx b/web/src/pages/agent/form/agent-form/tool-popover/tool-command.tsx index 5d948fe47..fd94408d8 100644 --- a/web/src/pages/agent/form/agent-form/tool-popover/tool-command.tsx +++ b/web/src/pages/agent/form/agent-form/tool-popover/tool-command.tsx @@ -16,7 +16,7 @@ const Menus = [ { label: 'Search', list: [ - Operator.Tavily, + Operator.TavilySearch, Operator.Google, Operator.Bing, Operator.DuckDuckGo, diff --git a/web/src/pages/agent/form/tool-form/constant.ts b/web/src/pages/agent/form/tool-form/constant.ts index 4954f51e1..73f6f7b6d 100644 --- a/web/src/pages/agent/form/tool-form/constant.ts +++ b/web/src/pages/agent/form/tool-form/constant.ts @@ -34,5 +34,5 @@ export const ToolFormConfigMap = { [Operator.YahooFinance]: YahooFinanceForm, [Operator.Crawler]: CrawlerForm, [Operator.Email]: EmailForm, - [Operator.Tavily]: TavilyForm, + [Operator.TavilySearch]: TavilyForm, }; diff --git a/web/src/pages/agent/hooks.tsx b/web/src/pages/agent/hooks.tsx index b8344f7bf..507d73e76 100644 --- a/web/src/pages/agent/hooks.tsx +++ b/web/src/pages/agent/hooks.tsx @@ -150,7 +150,7 @@ export const useInitializeOperatorParams = () => { [Operator.Code]: initialCodeValues, [Operator.WaitingDialogue]: initialWaitingDialogueValues, [Operator.Agent]: { ...initialAgentValues, llm_id: llmId }, - [Operator.Tavily]: initialTavilyValues, + [Operator.TavilySearch]: initialTavilyValues, }; }, [llmId]); diff --git a/web/src/pages/agent/hooks/use-add-node.ts b/web/src/pages/agent/hooks/use-add-node.ts index 0a74eac22..0bc58d025 100644 --- a/web/src/pages/agent/hooks/use-add-node.ts +++ b/web/src/pages/agent/hooks/use-add-node.ts @@ -105,7 +105,7 @@ export const useInitializeOperatorParams = () => { [Operator.WaitingDialogue]: initialWaitingDialogueValues, [Operator.Agent]: { ...initialAgentValues, llm_id: llmId }, [Operator.Tool]: {}, - [Operator.Tavily]: initialTavilyValues, + [Operator.TavilySearch]: initialTavilyValues, }; }, [llmId]); diff --git a/web/src/pages/agent/utils.ts b/web/src/pages/agent/utils.ts index e86e0c395..f67042285 100644 --- a/web/src/pages/agent/utils.ts +++ b/web/src/pages/agent/utils.ts @@ -94,9 +94,20 @@ const buildComponentDownstreamOrUpstream = ( edges: Edge[], nodeId: string, isBuildDownstream = true, + nodes: Node[], ) => { return edges - .filter((y) => y[isBuildDownstream ? 'source' : 'target'] === nodeId) + .filter((y) => { + const node = nodes.find((x) => x.id === nodeId); + let isNotUpstreamTool = true; + if (isBuildDownstream && node?.data.label === Operator.Agent) { + isNotUpstreamTool = !y.target.startsWith(Operator.Tool); // Exclude the tool operator downstream of the agent operator + } + return ( + y[isBuildDownstream ? 'source' : 'target'] === nodeId && + isNotUpstreamTool + ); + }) .map((y) => y[isBuildDownstream ? 'target' : 'source']); }; @@ -125,6 +136,8 @@ const buildOperatorParams = (operatorName: string) => // initializeOperatorParams(operatorName), // Final processing, for guarantee ); +const ExcludeOperators = [Operator.Note, Operator.Tool]; + // construct a dsl based on the node information of the graph export const buildDslComponentsByGraph = ( nodes: RAGFlowNodeType[], @@ -134,7 +147,7 @@ export const buildDslComponentsByGraph = ( const components: DSLComponents = {}; nodes - ?.filter((x) => x.data.label !== Operator.Note) + ?.filter((x) => !ExcludeOperators.some((y) => y === x.data.label)) .forEach((x) => { const id = x.id; const operatorName = x.data.label; @@ -147,8 +160,8 @@ export const buildDslComponentsByGraph = ( x.data.form as Record, ) ?? {}, }, - downstream: buildComponentDownstreamOrUpstream(edges, id, true), - upstream: buildComponentDownstreamOrUpstream(edges, id, false), + downstream: buildComponentDownstreamOrUpstream(edges, id, true, nodes), + upstream: buildComponentDownstreamOrUpstream(edges, id, false, nodes), parent_id: x?.parentId, }; });