mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-04-08 03:00:28 -04:00
fix(frontend/builder): Fix moved blocks disappearing on save (#10951)
- Resolves #10926 - Fixes a bug introduced in #10779 ### Changes 🏗️ - Fix `.metadata.position` in graph save payload - Make node reconciliation after graph save more robust ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - [x] Moved nodes don't disappear on graph save
This commit is contained in:
committed by
GitHub
parent
a978e91271
commit
3f19cba28f
@@ -161,60 +161,14 @@ export default function useAgentGraph(
|
||||
setAgentDescription(graph.description);
|
||||
setAgentRecommendedScheduleCron(graph.recommended_schedule_cron || "");
|
||||
|
||||
const getGraphName = (node: Node) => {
|
||||
if (node.input_default.agent_name) {
|
||||
return node.input_default.agent_name;
|
||||
}
|
||||
return (
|
||||
availableFlows.find((flow) => flow.id === node.input_default.graph_id)
|
||||
?.name || null
|
||||
);
|
||||
};
|
||||
|
||||
setXYNodes((prevNodes) => {
|
||||
const _newNodes = graph.nodes.map((node) => {
|
||||
const block = availableBlocks.find(
|
||||
(block) => block.id === node.block_id,
|
||||
)!;
|
||||
if (!block) return null;
|
||||
const prevNode = prevNodes.find((n) => n.id === node.id);
|
||||
const graphName =
|
||||
(block.uiType == BlockUIType.AGENT && getGraphName(node)) || null;
|
||||
const newNode: CustomNode = {
|
||||
id: node.id,
|
||||
type: "custom",
|
||||
position: {
|
||||
x: node?.metadata?.position?.x || 0,
|
||||
y: node?.metadata?.position?.y || 0,
|
||||
},
|
||||
data: {
|
||||
isOutputOpen: false,
|
||||
...prevNode?.data,
|
||||
block_id: block.id,
|
||||
blockType: graphName || block.name,
|
||||
blockCosts: block.costs,
|
||||
categories: block.categories,
|
||||
description: block.description,
|
||||
title: `${block.name} ${node.id}`,
|
||||
inputSchema: block.inputSchema,
|
||||
outputSchema: block.outputSchema,
|
||||
hardcodedValues: node.input_default,
|
||||
uiType: block.uiType,
|
||||
metadata: node.metadata,
|
||||
connections: graph.links
|
||||
.filter((l) => [l.source_id, l.sink_id].includes(node.id))
|
||||
.map((link) => ({
|
||||
edge_id: formatEdgeID(link),
|
||||
source: link.source_id,
|
||||
sourceHandle: link.source_name,
|
||||
target: link.sink_id,
|
||||
targetHandle: link.sink_name,
|
||||
})),
|
||||
backend_id: node.id,
|
||||
},
|
||||
};
|
||||
return newNode;
|
||||
});
|
||||
const _newNodes = graph.nodes.map((node) =>
|
||||
_backendNodeToXYNode(
|
||||
node,
|
||||
graph,
|
||||
prevNodes.find((n) => n.id === node.id),
|
||||
),
|
||||
);
|
||||
const newNodes = _newNodes.filter((n) => n !== null);
|
||||
setXYEdges(() =>
|
||||
graph.links.map((link) => {
|
||||
@@ -250,6 +204,63 @@ export default function useAgentGraph(
|
||||
});
|
||||
}
|
||||
|
||||
function _backendNodeToXYNode(
|
||||
node: Node,
|
||||
graph: Graph,
|
||||
prevNode?: CustomNode,
|
||||
): CustomNode | null {
|
||||
const block = availableBlocks.find((block) => block.id === node.block_id)!;
|
||||
if (!block) return null;
|
||||
|
||||
const { position, ...metadata } = node.metadata;
|
||||
const subGraphName =
|
||||
(block.uiType == BlockUIType.AGENT && _getSubGraphName(node)) || null;
|
||||
|
||||
return {
|
||||
id: node.id,
|
||||
type: "custom",
|
||||
position: {
|
||||
x: position?.x || 0,
|
||||
y: position?.y || 0,
|
||||
},
|
||||
data: {
|
||||
isOutputOpen: false,
|
||||
...prevNode?.data,
|
||||
block_id: block.id,
|
||||
blockType: subGraphName || block.name,
|
||||
blockCosts: block.costs,
|
||||
categories: block.categories,
|
||||
description: block.description,
|
||||
title: `${block.name} ${node.id}`,
|
||||
inputSchema: block.inputSchema,
|
||||
outputSchema: block.outputSchema,
|
||||
hardcodedValues: node.input_default,
|
||||
uiType: block.uiType,
|
||||
metadata: metadata,
|
||||
connections: graph.links
|
||||
.filter((l) => [l.source_id, l.sink_id].includes(node.id))
|
||||
.map((link) => ({
|
||||
edge_id: formatEdgeID(link),
|
||||
source: link.source_id,
|
||||
sourceHandle: link.source_name,
|
||||
target: link.sink_id,
|
||||
targetHandle: link.sink_name,
|
||||
})),
|
||||
backend_id: node.id,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const _getSubGraphName = (node: Node) => {
|
||||
if (node.input_default.agent_name) {
|
||||
return node.input_default.agent_name;
|
||||
}
|
||||
return (
|
||||
availableFlows.find((flow) => flow.id === node.input_default.graph_id)
|
||||
?.name || null
|
||||
);
|
||||
};
|
||||
|
||||
const getFrontendId = useCallback(
|
||||
(backendId: string, nodes: CustomNode[]) => {
|
||||
const node = nodes.find((node) => node.data.backend_id === backendId);
|
||||
@@ -622,8 +633,8 @@ export default function useAgentGraph(
|
||||
block_id: node.data.block_id,
|
||||
input_default: prepareNodeInputData(node),
|
||||
metadata: {
|
||||
...(node.data.metadata ?? {}),
|
||||
position: node.position,
|
||||
...(node.data.metadata || {}),
|
||||
},
|
||||
}),
|
||||
),
|
||||
@@ -641,7 +652,7 @@ export default function useAgentGraph(
|
||||
|
||||
const _saveAgent = useCallback(async () => {
|
||||
// FIXME: frontend IDs should be resolved better (e.g. returned from the server)
|
||||
// currently this relays on block_id and position
|
||||
// currently this relies on block_id and position
|
||||
const blockIDToNodeIDMap = Object.fromEntries(
|
||||
xyNodes.map((node) => [
|
||||
`${node.data.block_id}_${node.position.x}_${node.position.y}`,
|
||||
@@ -691,10 +702,11 @@ export default function useAgentGraph(
|
||||
const frontendNodeID = blockIDToNodeIDMap[key];
|
||||
const frontendNode = prev.find((node) => node.id === frontendNodeID);
|
||||
|
||||
const { position, ...metadata } = backendNode.metadata;
|
||||
return frontendNode
|
||||
? {
|
||||
? ({
|
||||
...frontendNode,
|
||||
position: backendNode.metadata.position,
|
||||
position,
|
||||
data: {
|
||||
...frontendNode.data,
|
||||
hardcodedValues: removeEmptyStringsAndNulls(
|
||||
@@ -702,12 +714,11 @@ export default function useAgentGraph(
|
||||
),
|
||||
status: undefined,
|
||||
backend_id: backendNode.id,
|
||||
webhook: backendNode.webhook,
|
||||
executionResults: [],
|
||||
metadata: backendNode.metadata,
|
||||
metadata,
|
||||
},
|
||||
}
|
||||
: null;
|
||||
} satisfies CustomNode)
|
||||
: _backendNodeToXYNode(backendNode, newSavedAgent); // fallback
|
||||
})
|
||||
.filter((node) => node !== null);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user