mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-06-26 22:19:57 +00:00
### What problem does this PR solve? Feat: Deleting the last tool of the agent will delete the tool node #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
fa3e90c72e
commit
972fd919b4
@ -1,8 +1,9 @@
|
|||||||
import { IAgentForm, IToolNode } from '@/interfaces/database/agent';
|
import { IAgentForm, IToolNode } from '@/interfaces/database/agent';
|
||||||
import { Handle, NodeProps, Position } from '@xyflow/react';
|
import { Handle, NodeProps, Position } from '@xyflow/react';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { memo } from 'react';
|
import { memo, useCallback } from 'react';
|
||||||
import { NodeHandleId } from '../../constant';
|
import { NodeHandleId } from '../../constant';
|
||||||
|
import { ToolCard } from '../../form/agent-form/agent-tools';
|
||||||
import useGraphStore from '../../store';
|
import useGraphStore from '../../store';
|
||||||
import { NodeWrapper } from './node-wrapper';
|
import { NodeWrapper } from './node-wrapper';
|
||||||
|
|
||||||
@ -16,6 +17,8 @@ function InnerToolNode({
|
|||||||
const upstreamAgentNodeId = edges.find((x) => x.target === id)?.source;
|
const upstreamAgentNodeId = edges.find((x) => x.target === id)?.source;
|
||||||
const upstreamAgentNode = getNode(upstreamAgentNodeId);
|
const upstreamAgentNode = getNode(upstreamAgentNodeId);
|
||||||
|
|
||||||
|
const handleClick = useCallback(() => {}, []);
|
||||||
|
|
||||||
const tools: IAgentForm['tools'] = get(
|
const tools: IAgentForm['tools'] = get(
|
||||||
upstreamAgentNode,
|
upstreamAgentNode,
|
||||||
'data.form.tools',
|
'data.form.tools',
|
||||||
@ -30,9 +33,16 @@ function InnerToolNode({
|
|||||||
position={Position.Top}
|
position={Position.Top}
|
||||||
isConnectable={isConnectable}
|
isConnectable={isConnectable}
|
||||||
></Handle>
|
></Handle>
|
||||||
<ul className="space-y-1">
|
<ul className="space-y-2">
|
||||||
{tools.map((x) => (
|
{tools.map((x) => (
|
||||||
<li key={x.component_name}>{x.component_name}</li>
|
<ToolCard
|
||||||
|
key={x.component_name}
|
||||||
|
onClick={handleClick}
|
||||||
|
className="cursor-pointer"
|
||||||
|
data-tool={x.component_name}
|
||||||
|
>
|
||||||
|
{x.component_name}
|
||||||
|
</ToolCard>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</NodeWrapper>
|
</NodeWrapper>
|
||||||
|
53
web/src/pages/agent/form/agent-form/agent-tools.tsx
Normal file
53
web/src/pages/agent/form/agent-form/agent-tools.tsx
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { BlockButton } from '@/components/ui/button';
|
||||||
|
import { cn } from '@/lib/utils';
|
||||||
|
import { PencilLine, X } from 'lucide-react';
|
||||||
|
import { PropsWithChildren } from 'react';
|
||||||
|
import { ToolPopover } from './tool-popover';
|
||||||
|
import { useDeleteAgentNodeTools } from './tool-popover/use-update-tools';
|
||||||
|
import { useGetAgentToolNames } from './use-get-tools';
|
||||||
|
|
||||||
|
export function ToolCard({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
...props
|
||||||
|
}: PropsWithChildren & React.HTMLAttributes<HTMLLIElement>) {
|
||||||
|
return (
|
||||||
|
<li
|
||||||
|
{...props}
|
||||||
|
className={cn(
|
||||||
|
'flex bg-background-card p-1 rounded-sm justify-between',
|
||||||
|
className,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AgentTools() {
|
||||||
|
const { toolNames } = useGetAgentToolNames();
|
||||||
|
const { deleteNodeTool } = useDeleteAgentNodeTools();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section className="space-y-2.5">
|
||||||
|
<span className="text-text-sub-title">Tools</span>
|
||||||
|
<ul className="space-y-2">
|
||||||
|
{toolNames.map((x) => (
|
||||||
|
<ToolCard key={x}>
|
||||||
|
{x}
|
||||||
|
<div className="flex items-center gap-2 text-text-sub-title">
|
||||||
|
<PencilLine className="size-4 cursor-pointer" />
|
||||||
|
<X
|
||||||
|
className="size-4 cursor-pointer"
|
||||||
|
onClick={deleteNodeTool(x)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ToolCard>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
<ToolPopover>
|
||||||
|
<BlockButton>Add Tool</BlockButton>
|
||||||
|
</ToolPopover>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
|
}
|
@ -21,8 +21,8 @@ import { AgentInstanceContext } from '../../context';
|
|||||||
import { INextOperatorForm } from '../../interface';
|
import { INextOperatorForm } from '../../interface';
|
||||||
import { Output } from '../components/output';
|
import { Output } from '../components/output';
|
||||||
import { PromptEditor } from '../components/prompt-editor';
|
import { PromptEditor } from '../components/prompt-editor';
|
||||||
import { ToolPopover } from './tool-popover';
|
import { AgentTools } from './agent-tools';
|
||||||
import { useToolOptions, useValues } from './use-values';
|
import { useValues } from './use-values';
|
||||||
import { useWatchFormChange } from './use-watch-change';
|
import { useWatchFormChange } from './use-watch-change';
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
@ -67,8 +67,6 @@ const AgentForm = ({ node }: INextOperatorForm) => {
|
|||||||
|
|
||||||
const { addCanvasNode } = useContext(AgentInstanceContext);
|
const { addCanvasNode } = useContext(AgentInstanceContext);
|
||||||
|
|
||||||
const toolOptions = useToolOptions();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
<form
|
<form
|
||||||
@ -113,17 +111,17 @@ const AgentForm = ({ node }: INextOperatorForm) => {
|
|||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
</FormContainer>
|
</FormContainer>
|
||||||
<ToolPopover>
|
<FormContainer>
|
||||||
<BlockButton>Add Tool</BlockButton>
|
<AgentTools></AgentTools>
|
||||||
</ToolPopover>
|
<BlockButton
|
||||||
<BlockButton
|
onClick={addCanvasNode(Operator.Agent, {
|
||||||
onClick={addCanvasNode(Operator.Agent, {
|
nodeId: node?.id,
|
||||||
nodeId: node?.id,
|
position: Position.Bottom,
|
||||||
position: Position.Bottom,
|
})}
|
||||||
})}
|
>
|
||||||
>
|
Add Agent
|
||||||
Add Agent
|
</BlockButton>
|
||||||
</BlockButton>
|
</FormContainer>
|
||||||
<Output list={outputList}></Output>
|
<Output list={outputList}></Output>
|
||||||
</form>
|
</form>
|
||||||
</Form>
|
</Form>
|
||||||
|
@ -3,12 +3,12 @@ import {
|
|||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
} from '@/components/ui/popover';
|
} from '@/components/ui/popover';
|
||||||
import { IAgentForm } from '@/interfaces/database/agent';
|
|
||||||
import { Operator } from '@/pages/agent/constant';
|
import { Operator } from '@/pages/agent/constant';
|
||||||
import { AgentFormContext, AgentInstanceContext } from '@/pages/agent/context';
|
import { AgentFormContext, AgentInstanceContext } from '@/pages/agent/context';
|
||||||
import { Position } from '@xyflow/react';
|
import { Position } from '@xyflow/react';
|
||||||
import { get } from 'lodash';
|
import { PropsWithChildren, useCallback, useContext } from 'react';
|
||||||
import { PropsWithChildren, useCallback, useContext, useMemo } from 'react';
|
import { useDeleteToolNode } from '../use-delete-tool-node';
|
||||||
|
import { useGetAgentToolNames } from '../use-get-tools';
|
||||||
import { ToolCommand } from './tool-command';
|
import { ToolCommand } from './tool-command';
|
||||||
import { useUpdateAgentNodeTools } from './use-update-tools';
|
import { useUpdateAgentNodeTools } from './use-update-tools';
|
||||||
|
|
||||||
@ -16,23 +16,24 @@ export function ToolPopover({ children }: PropsWithChildren) {
|
|||||||
const { addCanvasNode } = useContext(AgentInstanceContext);
|
const { addCanvasNode } = useContext(AgentInstanceContext);
|
||||||
const node = useContext(AgentFormContext);
|
const node = useContext(AgentFormContext);
|
||||||
const { updateNodeTools } = useUpdateAgentNodeTools();
|
const { updateNodeTools } = useUpdateAgentNodeTools();
|
||||||
|
const { toolNames } = useGetAgentToolNames();
|
||||||
const toolNames = useMemo(() => {
|
const { deleteToolNode } = useDeleteToolNode();
|
||||||
const tools: IAgentForm['tools'] = get(node, 'data.form.tools', []);
|
|
||||||
return tools.map((x) => x.component_name);
|
|
||||||
}, [node]);
|
|
||||||
|
|
||||||
const handleChange = useCallback(
|
const handleChange = useCallback(
|
||||||
(value: string[]) => {
|
(value: string[]) => {
|
||||||
if (Array.isArray(value) && value.length > 0 && node?.id) {
|
if (Array.isArray(value) && node?.id) {
|
||||||
updateNodeTools(value);
|
updateNodeTools(value);
|
||||||
addCanvasNode(Operator.Tool, {
|
if (value.length > 0) {
|
||||||
position: Position.Bottom,
|
addCanvasNode(Operator.Tool, {
|
||||||
nodeId: node?.id,
|
position: Position.Bottom,
|
||||||
})();
|
nodeId: node?.id,
|
||||||
|
})();
|
||||||
|
} else {
|
||||||
|
deleteToolNode(node.id); // TODO: The tool node should be derived from the agent tools data
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[addCanvasNode, node?.id, updateNodeTools],
|
[addCanvasNode, deleteToolNode, node?.id, updateNodeTools],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -2,17 +2,26 @@ import { IAgentForm } from '@/interfaces/database/agent';
|
|||||||
import { AgentFormContext } from '@/pages/agent/context';
|
import { AgentFormContext } from '@/pages/agent/context';
|
||||||
import useGraphStore from '@/pages/agent/store';
|
import useGraphStore from '@/pages/agent/store';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { useCallback, useContext } from 'react';
|
import { useCallback, useContext, useMemo } from 'react';
|
||||||
|
import { useDeleteToolNode } from '../use-delete-tool-node';
|
||||||
|
|
||||||
|
export function useGetNodeTools() {
|
||||||
|
const node = useContext(AgentFormContext);
|
||||||
|
|
||||||
|
return useMemo(() => {
|
||||||
|
const tools: IAgentForm['tools'] = get(node, 'data.form.tools');
|
||||||
|
return tools;
|
||||||
|
}, [node]);
|
||||||
|
}
|
||||||
|
|
||||||
export function useUpdateAgentNodeTools() {
|
export function useUpdateAgentNodeTools() {
|
||||||
const { updateNodeForm } = useGraphStore((state) => state);
|
const { updateNodeForm } = useGraphStore((state) => state);
|
||||||
const node = useContext(AgentFormContext);
|
const node = useContext(AgentFormContext);
|
||||||
|
const tools = useGetNodeTools();
|
||||||
|
|
||||||
const updateNodeTools = useCallback(
|
const updateNodeTools = useCallback(
|
||||||
(value: string[]) => {
|
(value: string[]) => {
|
||||||
if (node?.id) {
|
if (node?.id) {
|
||||||
const tools: IAgentForm['tools'] = get(node, 'data.form.tools');
|
|
||||||
|
|
||||||
const nextValue = value.reduce<IAgentForm['tools']>((pre, cur) => {
|
const nextValue = value.reduce<IAgentForm['tools']>((pre, cur) => {
|
||||||
const tool = tools.find((x) => x.component_name === cur);
|
const tool = tools.find((x) => x.component_name === cur);
|
||||||
pre.push(tool ? tool : { component_name: cur, params: {} });
|
pre.push(tool ? tool : { component_name: cur, params: {} });
|
||||||
@ -22,8 +31,37 @@ export function useUpdateAgentNodeTools() {
|
|||||||
updateNodeForm(node?.id, nextValue, ['tools']);
|
updateNodeForm(node?.id, nextValue, ['tools']);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[node, updateNodeForm],
|
[node?.id, tools, updateNodeForm],
|
||||||
);
|
);
|
||||||
|
|
||||||
return { updateNodeTools };
|
const deleteNodeTool = useCallback(
|
||||||
|
(value: string) => {
|
||||||
|
updateNodeTools([value]);
|
||||||
|
},
|
||||||
|
[updateNodeTools],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { updateNodeTools, deleteNodeTool };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useDeleteAgentNodeTools() {
|
||||||
|
const { updateNodeForm } = useGraphStore((state) => state);
|
||||||
|
const tools = useGetNodeTools();
|
||||||
|
const node = useContext(AgentFormContext);
|
||||||
|
const { deleteToolNode } = useDeleteToolNode();
|
||||||
|
|
||||||
|
const deleteNodeTool = useCallback(
|
||||||
|
(value: string) => () => {
|
||||||
|
const nextTools = tools.filter((x) => x.component_name !== value);
|
||||||
|
if (node?.id) {
|
||||||
|
updateNodeForm(node?.id, nextTools, ['tools']);
|
||||||
|
if (nextTools.length === 0) {
|
||||||
|
deleteToolNode(node?.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[deleteToolNode, node?.id, tools, updateNodeForm],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { deleteNodeTool };
|
||||||
}
|
}
|
||||||
|
24
web/src/pages/agent/form/agent-form/use-delete-tool-node.ts
Normal file
24
web/src/pages/agent/form/agent-form/use-delete-tool-node.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { useCallback } from 'react';
|
||||||
|
import { NodeHandleId } from '../../constant';
|
||||||
|
import useGraphStore from '../../store';
|
||||||
|
|
||||||
|
export function useDeleteToolNode() {
|
||||||
|
const { edges, deleteEdgeById, deleteNodeById } = useGraphStore(
|
||||||
|
(state) => state,
|
||||||
|
);
|
||||||
|
const deleteToolNode = useCallback(
|
||||||
|
(agentNodeId: string) => {
|
||||||
|
const edge = edges.find(
|
||||||
|
(x) => x.source === agentNodeId && x.sourceHandle === NodeHandleId.Tool,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (edge) {
|
||||||
|
deleteEdgeById(edge.id);
|
||||||
|
deleteNodeById(edge.target);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[deleteEdgeById, deleteNodeById, edges],
|
||||||
|
);
|
||||||
|
|
||||||
|
return { deleteToolNode };
|
||||||
|
}
|
15
web/src/pages/agent/form/agent-form/use-get-tools.ts
Normal file
15
web/src/pages/agent/form/agent-form/use-get-tools.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { IAgentForm } from '@/interfaces/database/agent';
|
||||||
|
import { get } from 'lodash';
|
||||||
|
import { useContext, useMemo } from 'react';
|
||||||
|
import { AgentFormContext } from '../../context';
|
||||||
|
|
||||||
|
export function useGetAgentToolNames() {
|
||||||
|
const node = useContext(AgentFormContext);
|
||||||
|
|
||||||
|
const toolNames = useMemo(() => {
|
||||||
|
const tools: IAgentForm['tools'] = get(node, 'data.form.tools', []);
|
||||||
|
return tools.map((x) => x.component_name);
|
||||||
|
}, [node]);
|
||||||
|
|
||||||
|
return { toolNames };
|
||||||
|
}
|
@ -2,7 +2,7 @@ import { useFetchModelId } from '@/hooks/logic-hooks';
|
|||||||
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
import { RAGFlowNodeType } from '@/interfaces/database/flow';
|
||||||
import { get, isEmpty } from 'lodash';
|
import { get, isEmpty } from 'lodash';
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { Operator, initialAgentValues } from '../../constant';
|
import { initialAgentValues } from '../../constant';
|
||||||
|
|
||||||
export function useValues(node?: RAGFlowNodeType) {
|
export function useValues(node?: RAGFlowNodeType) {
|
||||||
const llmId = useFetchModelId();
|
const llmId = useFetchModelId();
|
||||||
@ -28,48 +28,3 @@ export function useValues(node?: RAGFlowNodeType) {
|
|||||||
|
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildOptions(list: string[]) {
|
|
||||||
return list.map((x) => ({ label: x, value: x }));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function useToolOptions() {
|
|
||||||
const options = useMemo(() => {
|
|
||||||
const options = [
|
|
||||||
{
|
|
||||||
label: 'Search',
|
|
||||||
options: buildOptions([
|
|
||||||
Operator.Google,
|
|
||||||
Operator.Bing,
|
|
||||||
Operator.DuckDuckGo,
|
|
||||||
Operator.Wikipedia,
|
|
||||||
Operator.YahooFinance,
|
|
||||||
Operator.PubMed,
|
|
||||||
Operator.GoogleScholar,
|
|
||||||
]),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Communication',
|
|
||||||
options: buildOptions([Operator.Email]),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Productivity',
|
|
||||||
options: [],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'Developer',
|
|
||||||
options: buildOptions([
|
|
||||||
Operator.GitHub,
|
|
||||||
Operator.ExeSQL,
|
|
||||||
Operator.Invoke,
|
|
||||||
Operator.Crawler,
|
|
||||||
Operator.Code,
|
|
||||||
]),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return options;
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,7 @@ import { INextOperatorForm } from '../../interface';
|
|||||||
import { useValues } from './use-values';
|
import { useValues } from './use-values';
|
||||||
import { useWatchFormChange } from './use-watch-change';
|
import { useWatchFormChange } from './use-watch-change';
|
||||||
|
|
||||||
const MessageForm = ({ node }: INextOperatorForm) => {
|
const TavilyForm = ({ node }: INextOperatorForm) => {
|
||||||
const values = useValues(node);
|
const values = useValues(node);
|
||||||
|
|
||||||
const FormSchema = z.object({
|
const FormSchema = z.object({
|
||||||
@ -58,4 +58,4 @@ const MessageForm = ({ node }: INextOperatorForm) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default MessageForm;
|
export default TavilyForm;
|
||||||
|
36
web/src/pages/agent/form/tool-form/constant.ts
Normal file
36
web/src/pages/agent/form/tool-form/constant.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { Operator } from '../../constant';
|
||||||
|
import AkShareForm from '../akshare-form';
|
||||||
|
import ArXivForm from '../arxiv-form';
|
||||||
|
import BingForm from '../bing-form';
|
||||||
|
import CodeForm from '../code-form';
|
||||||
|
import CrawlerForm from '../crawler-form';
|
||||||
|
import DeepLForm from '../deepl-form';
|
||||||
|
import DuckDuckGoForm from '../duckduckgo-form';
|
||||||
|
import EmailForm from '../email-form';
|
||||||
|
import ExeSQLForm from '../exesql-form';
|
||||||
|
import GithubForm from '../github-form';
|
||||||
|
import GoogleForm from '../google-form';
|
||||||
|
import GoogleScholarForm from '../google-scholar-form';
|
||||||
|
import PubMedForm from '../pubmed-form';
|
||||||
|
import RetrievalForm from '../retrieval-form/next';
|
||||||
|
import WikipediaForm from '../wikipedia-form';
|
||||||
|
import YahooFinanceForm from '../yahoo-finance-form';
|
||||||
|
|
||||||
|
export const ToolFormConfigMap = {
|
||||||
|
[Operator.Retrieval]: RetrievalForm,
|
||||||
|
[Operator.Code]: CodeForm,
|
||||||
|
[Operator.DuckDuckGo]: DuckDuckGoForm,
|
||||||
|
[Operator.Wikipedia]: WikipediaForm,
|
||||||
|
[Operator.PubMed]: PubMedForm,
|
||||||
|
[Operator.ArXiv]: ArXivForm,
|
||||||
|
[Operator.Google]: GoogleForm,
|
||||||
|
[Operator.Bing]: BingForm,
|
||||||
|
[Operator.GoogleScholar]: GoogleScholarForm,
|
||||||
|
[Operator.DeepL]: DeepLForm,
|
||||||
|
[Operator.GitHub]: GithubForm,
|
||||||
|
[Operator.ExeSQL]: ExeSQLForm,
|
||||||
|
[Operator.AkShare]: AkShareForm,
|
||||||
|
[Operator.YahooFinance]: YahooFinanceForm,
|
||||||
|
[Operator.Crawler]: CrawlerForm,
|
||||||
|
[Operator.Email]: EmailForm,
|
||||||
|
};
|
@ -1,7 +1,20 @@
|
|||||||
import { INextOperatorForm } from '../../interface';
|
import useGraphStore from '../../store';
|
||||||
|
import { ToolFormConfigMap } from './constant';
|
||||||
|
|
||||||
const ToolForm = ({ node }: INextOperatorForm) => {
|
const EmptyContent = () => <div></div>;
|
||||||
return <section>xxx</section>;
|
|
||||||
|
const ToolForm = () => {
|
||||||
|
const clickedToolId = useGraphStore((state) => state.clickedToolId);
|
||||||
|
|
||||||
|
const ToolForm =
|
||||||
|
ToolFormConfigMap[clickedToolId as keyof typeof ToolFormConfigMap] ??
|
||||||
|
EmptyContent;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<section>
|
||||||
|
<ToolForm key={clickedToolId}></ToolForm>
|
||||||
|
</section>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ToolForm;
|
export default ToolForm;
|
||||||
|
@ -184,7 +184,7 @@ function useAddChildEdge() {
|
|||||||
return { addChildEdge };
|
return { addChildEdge };
|
||||||
}
|
}
|
||||||
|
|
||||||
function useAddTooNode() {
|
function useAddToolNode() {
|
||||||
const addNode = useGraphStore((state) => state.addNode);
|
const addNode = useGraphStore((state) => state.addNode);
|
||||||
const getNode = useGraphStore((state) => state.getNode);
|
const getNode = useGraphStore((state) => state.getNode);
|
||||||
const addEdge = useGraphStore((state) => state.addEdge);
|
const addEdge = useGraphStore((state) => state.addEdge);
|
||||||
@ -241,7 +241,7 @@ export function useAddNode(reactFlowInstance?: ReactFlowInstance<any, any>) {
|
|||||||
const initializeOperatorParams = useInitializeOperatorParams();
|
const initializeOperatorParams = useInitializeOperatorParams();
|
||||||
const { calculateNewlyBackChildPosition } = useCalculateNewlyChildPosition();
|
const { calculateNewlyBackChildPosition } = useCalculateNewlyChildPosition();
|
||||||
const { addChildEdge } = useAddChildEdge();
|
const { addChildEdge } = useAddChildEdge();
|
||||||
const { addToolNode } = useAddTooNode();
|
const { addToolNode } = useAddToolNode();
|
||||||
// const [reactFlowInstance, setReactFlowInstance] =
|
// const [reactFlowInstance, setReactFlowInstance] =
|
||||||
// useState<ReactFlowInstance<any, any>>();
|
// useState<ReactFlowInstance<any, any>>();
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ export const useShowFormDrawer = () => {
|
|||||||
clickedNodeId: clickNodeId,
|
clickedNodeId: clickNodeId,
|
||||||
setClickedNodeId,
|
setClickedNodeId,
|
||||||
getNode,
|
getNode,
|
||||||
|
setClickedToolId,
|
||||||
} = useGraphStore((state) => state);
|
} = useGraphStore((state) => state);
|
||||||
const {
|
const {
|
||||||
visible: formDrawerVisible,
|
visible: formDrawerVisible,
|
||||||
@ -21,12 +22,13 @@ export const useShowFormDrawer = () => {
|
|||||||
showModal: showFormDrawer,
|
showModal: showFormDrawer,
|
||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
|
|
||||||
const handleShow = useCallback(
|
const handleShow: NodeMouseHandler = useCallback(
|
||||||
(node: Node) => {
|
(e, node: Node) => {
|
||||||
setClickedNodeId(node.id);
|
setClickedNodeId(node.id);
|
||||||
|
setClickedToolId(get(e.target, 'dataset.tool'));
|
||||||
showFormDrawer();
|
showFormDrawer();
|
||||||
},
|
},
|
||||||
[showFormDrawer, setClickedNodeId],
|
[setClickedNodeId, setClickedToolId, showFormDrawer],
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -118,7 +120,7 @@ export function useShowDrawer({
|
|||||||
if (!ExcludedNodes.some((x) => x === node.data.label)) {
|
if (!ExcludedNodes.some((x) => x === node.data.label)) {
|
||||||
hideSingleDebugDrawer();
|
hideSingleDebugDrawer();
|
||||||
hideRunOrChatDrawer();
|
hideRunOrChatDrawer();
|
||||||
showFormDrawer(node);
|
showFormDrawer(e, node);
|
||||||
}
|
}
|
||||||
// handle single debug icon click
|
// handle single debug icon click
|
||||||
if (
|
if (
|
||||||
|
@ -35,6 +35,7 @@ export type RFState = {
|
|||||||
selectedNodeIds: string[];
|
selectedNodeIds: string[];
|
||||||
selectedEdgeIds: string[];
|
selectedEdgeIds: string[];
|
||||||
clickedNodeId: string; // currently selected node
|
clickedNodeId: string; // currently selected node
|
||||||
|
clickedToolId: string; // currently selected tool id
|
||||||
onNodesChange: OnNodesChange<RAGFlowNodeType>;
|
onNodesChange: OnNodesChange<RAGFlowNodeType>;
|
||||||
onEdgesChange: OnEdgesChange;
|
onEdgesChange: OnEdgesChange;
|
||||||
onConnect: OnConnect;
|
onConnect: OnConnect;
|
||||||
@ -73,6 +74,7 @@ export type RFState = {
|
|||||||
updateNodeName: (id: string, name: string) => void;
|
updateNodeName: (id: string, name: string) => void;
|
||||||
generateNodeName: (name: string) => string;
|
generateNodeName: (name: string) => string;
|
||||||
setClickedNodeId: (id?: string) => void;
|
setClickedNodeId: (id?: string) => void;
|
||||||
|
setClickedToolId: (id?: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
// this is our useStore hook that we can use in our components to get parts of the store and call actions
|
||||||
@ -84,6 +86,7 @@ const useGraphStore = create<RFState>()(
|
|||||||
selectedNodeIds: [] as string[],
|
selectedNodeIds: [] as string[],
|
||||||
selectedEdgeIds: [] as string[],
|
selectedEdgeIds: [] as string[],
|
||||||
clickedNodeId: '',
|
clickedNodeId: '',
|
||||||
|
clickedToolId: '',
|
||||||
onNodesChange: (changes) => {
|
onNodesChange: (changes) => {
|
||||||
set({
|
set({
|
||||||
nodes: applyNodeChanges(changes, get().nodes),
|
nodes: applyNodeChanges(changes, get().nodes),
|
||||||
@ -465,6 +468,9 @@ const useGraphStore = create<RFState>()(
|
|||||||
|
|
||||||
return generateNodeNamesWithIncreasingIndex(name, nodes);
|
return generateNodeNamesWithIncreasingIndex(name, nodes);
|
||||||
},
|
},
|
||||||
|
setClickedToolId: (id?: string) => {
|
||||||
|
set({ clickedToolId: id });
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
{ name: 'graph', trace: true },
|
{ name: 'graph', trace: true },
|
||||||
),
|
),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user