Feat: Insert the node data of the bottom subagent into the tool array of the head agent #3221 (#8471)

### What problem does this PR solve?

Feat: Insert the node data of the bottom subagent into the tool array of
the head agent #3221

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu 2025-06-25 15:24:22 +08:00 committed by GitHub
parent 5256980ffb
commit ece27c66e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 48 additions and 12 deletions

View File

@ -17,10 +17,11 @@ import { useContext, useMemo } from 'react';
import { useForm } from 'react-hook-form'; import { useForm } from 'react-hook-form';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { z } from 'zod'; import { z } from 'zod';
import { NodeHandleId, Operator, initialAgentValues } from '../../constant'; import { Operator, initialAgentValues } from '../../constant';
import { AgentInstanceContext } from '../../context'; import { AgentInstanceContext } from '../../context';
import { INextOperatorForm } from '../../interface'; import { INextOperatorForm } from '../../interface';
import useGraphStore from '../../store'; import useGraphStore from '../../store';
import { isBottomSubAgent } from '../../utils';
import { Output } from '../components/output'; import { Output } from '../components/output';
import { PromptEditor } from '../components/prompt-editor'; import { PromptEditor } from '../components/prompt-editor';
import { AgentTools } from './agent-tools'; import { AgentTools } from './agent-tools';
@ -57,10 +58,7 @@ const AgentForm = ({ node }: INextOperatorForm) => {
const defaultValues = useValues(node); const defaultValues = useValues(node);
const isSubAgent = useMemo(() => { const isSubAgent = useMemo(() => {
const edge = edges.find( return isBottomSubAgent(edges, node?.id);
(x) => x.target === node?.id && x.targetHandle === NodeHandleId.AgentTop,
);
return !!edge;
}, [edges, node?.id]); }, [edges, node?.id]);
const outputList = useMemo(() => { const outputList = useMemo(() => {

View File

@ -15,6 +15,7 @@ import { v4 as uuidv4 } from 'uuid';
import { import {
CategorizeAnchorPointPositions, CategorizeAnchorPointPositions,
NoDebugOperatorsList, NoDebugOperatorsList,
NodeHandleId,
NodeMap, NodeMap,
Operator, Operator,
} from './constant'; } from './constant';
@ -100,12 +101,20 @@ const buildComponentDownstreamOrUpstream = (
.filter((y) => { .filter((y) => {
const node = nodes.find((x) => x.id === nodeId); const node = nodes.find((x) => x.id === nodeId);
let isNotUpstreamTool = true; let isNotUpstreamTool = true;
let isNotUpstreamAgent = true;
if (isBuildDownstream && node?.data.label === Operator.Agent) { if (isBuildDownstream && node?.data.label === Operator.Agent) {
isNotUpstreamTool = !y.target.startsWith(Operator.Tool); // Exclude the tool operator downstream of the agent operator // Exclude the tool operator downstream of the agent operator
isNotUpstreamTool = !y.target.startsWith(Operator.Tool);
// Exclude the agent operator downstream of the agent operator
isNotUpstreamAgent = !(
y.target.startsWith(Operator.Agent) &&
y.targetHandle === NodeHandleId.AgentTop
);
} }
return ( return (
y[isBuildDownstream ? 'source' : 'target'] === nodeId && y[isBuildDownstream ? 'source' : 'target'] === nodeId &&
isNotUpstreamTool isNotUpstreamTool &&
isNotUpstreamAgent
); );
}) })
.map((y) => y[isBuildDownstream ? 'target' : 'source']); .map((y) => y[isBuildDownstream ? 'target' : 'source']);
@ -130,6 +139,25 @@ const removeUselessDataInTheOperator = curry(
// return values; // return values;
// }); // });
function buildAgentTools(edges: Edge[], nodes: Node[], nodeId: string) {
const node = nodes.find((x) => x.id === nodeId);
const params = { ...(node?.data.form ?? {}) };
if (node && node.data.label === Operator.Agent) {
const bottomSubAgentEdges = edges.filter(
(x) => x.source === nodeId && x.sourceHandle === NodeHandleId.AgentBottom,
);
(params as IAgentForm).tools = (params as IAgentForm).tools.concat(
bottomSubAgentEdges.map((x) => {
const formData = buildAgentTools(edges, nodes, x.target);
return { component_name: Operator.Agent, params: { ...formData } };
}),
);
}
return params;
}
const buildOperatorParams = (operatorName: string) => const buildOperatorParams = (operatorName: string) =>
pipe( pipe(
removeUselessDataInTheOperator(operatorName), removeUselessDataInTheOperator(operatorName),
@ -138,6 +166,13 @@ const buildOperatorParams = (operatorName: string) =>
const ExcludeOperators = [Operator.Note, Operator.Tool]; const ExcludeOperators = [Operator.Note, Operator.Tool];
export function isBottomSubAgent(edges: Edge[], nodeId?: string) {
const edge = edges.find(
(x) => x.target === nodeId && x.targetHandle === NodeHandleId.AgentTop,
);
return !!edge;
}
// construct a dsl based on the node information of the graph // construct a dsl based on the node information of the graph
export const buildDslComponentsByGraph = ( export const buildDslComponentsByGraph = (
nodes: RAGFlowNodeType[], nodes: RAGFlowNodeType[],
@ -147,18 +182,21 @@ export const buildDslComponentsByGraph = (
const components: DSLComponents = {}; const components: DSLComponents = {};
nodes nodes
?.filter((x) => !ExcludeOperators.some((y) => y === x.data.label)) ?.filter(
(x) =>
!ExcludeOperators.some((y) => y === x.data.label) &&
!isBottomSubAgent(edges, x.id),
)
.forEach((x) => { .forEach((x) => {
const id = x.id; const id = x.id;
const operatorName = x.data.label; const operatorName = x.data.label;
const params = buildAgentTools(edges, nodes, id);
components[id] = { components[id] = {
obj: { obj: {
...(oldDslComponents[id]?.obj ?? {}), ...(oldDslComponents[id]?.obj ?? {}),
component_name: operatorName, component_name: operatorName,
params: params: buildOperatorParams(operatorName)(params) ?? {},
buildOperatorParams(operatorName)(
x.data.form as Record<string, unknown>,
) ?? {},
}, },
downstream: buildComponentDownstreamOrUpstream(edges, id, true, nodes), downstream: buildComponentDownstreamOrUpstream(edges, id, true, nodes),
upstream: buildComponentDownstreamOrUpstream(edges, id, false, nodes), upstream: buildComponentDownstreamOrUpstream(edges, id, false, nodes),