fix: edges moving on just cloned flows (#6819)

* Changed export modal to just download after flow is built

* Changed cleanEdge to set edges animated to false

* Updated starter projects and tests to remove animated from edge

* update market research json to get global variable
This commit is contained in:
Lucas Oliveira 2025-02-26 17:46:54 -03:00 committed by GitHub
commit 7b3dc0b453
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 1072 additions and 1259 deletions

View file

@ -9,16 +9,12 @@
"dataType": "StructuredOutputComponent",
"id": "StructuredOutputComponent-Kqbq4",
"name": "structured_output",
"output_types": [
"Data"
]
"output_types": ["Data"]
},
"targetHandle": {
"fieldName": "data",
"id": "ParseData-7XOFR",
"inputTypes": [
"Data"
],
"inputTypes": ["Data"],
"type": "other"
}
},
@ -37,16 +33,12 @@
"dataType": "ChatInput",
"id": "ChatInput-tMLRq",
"name": "message",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "Agent-dcKuR",
"inputTypes": [
"Message"
],
"inputTypes": ["Message"],
"type": "str"
}
},
@ -58,23 +50,19 @@
"targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-dcKuRœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}"
},
{
"animated": true,
"animated": false,
"className": "",
"data": {
"sourceHandle": {
"dataType": "Agent",
"id": "Agent-dcKuR",
"name": "response",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "StructuredOutputComponent-Kqbq4",
"inputTypes": [
"Message"
],
"inputTypes": ["Message"],
"type": "str"
}
},
@ -93,16 +81,12 @@
"dataType": "TavilySearchComponent",
"id": "TavilySearchComponent-cGK9T",
"name": "component_as_tool",
"output_types": [
"Tool"
]
"output_types": ["Tool"]
},
"targetHandle": {
"fieldName": "tools",
"id": "Agent-dcKuR",
"inputTypes": [
"Tool"
],
"inputTypes": ["Tool"],
"type": "other"
}
},
@ -120,16 +104,12 @@
"dataType": "OpenAIModel",
"id": "OpenAIModel-prL67",
"name": "model_output",
"output_types": [
"LanguageModel"
]
"output_types": ["LanguageModel"]
},
"targetHandle": {
"fieldName": "llm",
"id": "StructuredOutputComponent-Kqbq4",
"inputTypes": [
"LanguageModel"
],
"inputTypes": ["LanguageModel"],
"type": "other"
}
},
@ -145,18 +125,12 @@
"dataType": "ParseData",
"id": "ParseData-7XOFR",
"name": "text",
"output_types": [
"Message"
]
"output_types": ["Message"]
},
"targetHandle": {
"fieldName": "input_value",
"id": "ChatOutput-JrLxU",
"inputTypes": [
"Data",
"DataFrame",
"Message"
],
"inputTypes": ["Data", "DataFrame", "Message"],
"type": "str"
}
},
@ -174,9 +148,7 @@
"display_name": "Chat Input",
"id": "ChatInput-tMLRq",
"node": {
"base_classes": [
"Message"
],
"base_classes": ["Message"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -210,9 +182,7 @@
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -225,9 +195,7 @@
"display_name": "Background Color",
"dynamic": false,
"info": "The background color of the icon.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "background_color",
@ -246,9 +214,7 @@
"display_name": "Icon",
"dynamic": false,
"info": "The icon of the message.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "chat_icon",
@ -349,10 +315,7 @@
"dynamic": false,
"info": "Type of sender.",
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"placeholder": "",
"required": false,
"show": true,
@ -367,9 +330,7 @@
"display_name": "Sender Name",
"dynamic": false,
"info": "Name of the sender.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "sender_name",
@ -388,9 +349,7 @@
"display_name": "Session ID",
"dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "session_id",
@ -425,9 +384,7 @@
"display_name": "Text Color",
"dynamic": false,
"info": "The text color of the name",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "text_color",
@ -469,9 +426,7 @@
"display_name": "Chat Output",
"id": "ChatOutput-JrLxU",
"node": {
"base_classes": [
"Message"
],
"base_classes": ["Message"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -505,9 +460,7 @@
"name": "message",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -520,9 +473,7 @@
"display_name": "Background Color",
"dynamic": false,
"info": "The background color of the icon.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "background_color",
@ -542,9 +493,7 @@
"display_name": "Icon",
"dynamic": false,
"info": "The icon of the message.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "chat_icon",
@ -600,9 +549,7 @@
"display_name": "Data Template",
"dynamic": false,
"info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "data_template",
@ -622,11 +569,7 @@
"display_name": "Text",
"dynamic": false,
"info": "Message to be passed as output.",
"input_types": [
"Data",
"DataFrame",
"Message"
],
"input_types": ["Data", "DataFrame", "Message"],
"list": false,
"load_from_db": false,
"name": "input_value",
@ -647,10 +590,7 @@
"dynamic": false,
"info": "Type of sender.",
"name": "sender",
"options": [
"Machine",
"User"
],
"options": ["Machine", "User"],
"placeholder": "",
"required": false,
"show": true,
@ -666,9 +606,7 @@
"display_name": "Sender Name",
"dynamic": false,
"info": "Name of the sender.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "sender_name",
@ -688,9 +626,7 @@
"display_name": "Session ID",
"dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "session_id",
@ -726,9 +662,7 @@
"display_name": "Text Color",
"dynamic": false,
"info": "The text color of the name",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "text_color",
@ -883,9 +817,7 @@
"display_name": "Structured Output",
"id": "StructuredOutputComponent-Kqbq4",
"node": {
"base_classes": [
"Data"
],
"base_classes": ["Data"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -913,9 +845,7 @@
"method": "build_structured_output",
"name": "structured_output",
"selected": "Data",
"types": [
"Data"
],
"types": ["Data"],
"value": "__UNDEFINED__"
}
],
@ -946,9 +876,7 @@
"display_name": "Input message",
"dynamic": false,
"info": "",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "input_value",
@ -968,9 +896,7 @@
"display_name": "Language Model",
"dynamic": false,
"info": "The language model to use to generate the structured output.",
"input_types": [
"LanguageModel"
],
"input_types": ["LanguageModel"],
"list": false,
"name": "llm",
"placeholder": "",
@ -1162,9 +1088,7 @@
"data": {
"id": "ParseData-7XOFR",
"node": {
"base_classes": [
"Message"
],
"base_classes": ["Message"],
"beta": false,
"category": "helpers",
"conditional_paths": [],
@ -1173,11 +1097,7 @@
"display_name": "Parse Data",
"documentation": "",
"edited": false,
"field_order": [
"data",
"template",
"sep"
],
"field_order": ["data", "template", "sep"],
"frozen": false,
"icon": "message-square",
"key": "ParseData",
@ -1196,9 +1116,7 @@
"name": "text",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
},
{
@ -1209,9 +1127,7 @@
"name": "data_list",
"selected": "Data",
"tool_mode": true,
"types": [
"Data"
],
"types": ["Data"],
"value": "__UNDEFINED__"
}
],
@ -1242,9 +1158,7 @@
"display_name": "Data",
"dynamic": false,
"info": "The data to convert to text.",
"input_types": [
"Data"
],
"input_types": ["Data"],
"list": true,
"name": "data",
"placeholder": "",
@ -1279,9 +1193,7 @@
"display_name": "Template",
"dynamic": false,
"info": "The template to use for formatting the data. It can contain the keys {text}, {data} or any other key in the Data.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1324,9 +1236,7 @@
"display_name": "Agent",
"id": "Agent-dcKuR",
"node": {
"base_classes": [
"Message"
],
"base_classes": ["Message"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -1377,9 +1287,7 @@
"name": "response",
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
}
],
@ -1408,9 +1316,7 @@
"display_name": "Agent Description [Deprecated]",
"dynamic": false,
"info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1461,9 +1367,7 @@
"display_name": "OpenAI API Key",
"dynamic": false,
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"load_from_db": true,
"name": "api_key",
"password": true,
@ -1514,9 +1418,7 @@
"display_name": "Input",
"dynamic": false,
"info": "The input provided by the user for the agent to process.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "input_value",
@ -1608,9 +1510,7 @@
"display_name": "External Memory",
"dynamic": false,
"info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.",
"input_types": [
"Memory"
],
"input_types": ["Memory"],
"list": false,
"name": "memory",
"placeholder": "",
@ -1704,10 +1604,7 @@
"dynamic": false,
"info": "Order of the messages.",
"name": "order",
"options": [
"Ascending",
"Descending"
],
"options": ["Ascending", "Descending"],
"placeholder": "",
"required": false,
"show": true,
@ -1741,11 +1638,7 @@
"dynamic": false,
"info": "Filter by sender type.",
"name": "sender",
"options": [
"Machine",
"User",
"Machine and User"
],
"options": ["Machine", "User", "Machine and User"],
"placeholder": "",
"required": false,
"show": true,
@ -1761,9 +1654,7 @@
"display_name": "Sender Name",
"dynamic": false,
"info": "Filter by sender name.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "sender_name",
@ -1783,9 +1674,7 @@
"display_name": "Session ID",
"dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"name": "session_id",
@ -1805,9 +1694,7 @@
"display_name": "Agent Instructions",
"dynamic": false,
"info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1844,9 +1731,7 @@
"display_name": "Template",
"dynamic": false,
"info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"load_from_db": false,
"multiline": true,
@ -1885,9 +1770,7 @@
"display_name": "Tools",
"dynamic": false,
"info": "These are the tools that the agent can use to help with tasks.",
"input_types": [
"Tool"
],
"input_types": ["Tool"],
"list": true,
"name": "tools",
"placeholder": "",
@ -1972,10 +1855,7 @@
"display_name": "Tavily AI Search",
"id": "TavilySearchComponent-cGK9T",
"node": {
"base_classes": [
"Data",
"Message"
],
"base_classes": ["Data", "Message"],
"beta": false,
"conditional_paths": [],
"custom_fields": {},
@ -2010,9 +1890,7 @@
"required_inputs": null,
"selected": "Tool",
"tool_mode": true,
"types": [
"Tool"
],
"types": ["Tool"],
"value": "__UNDEFINED__"
}
],
@ -2025,10 +1903,8 @@
"display_name": "Tavily API Key",
"dynamic": false,
"info": "Your Tavily API Key.",
"input_types": [
"Message"
],
"load_from_db": false,
"input_types": ["Message"],
"load_from_db": true,
"name": "api_key",
"password": true,
"placeholder": "",
@ -2116,9 +1992,7 @@
"display_name": "Search Query",
"dynamic": false,
"info": "The search query you want to execute with Tavily.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
@ -2142,10 +2016,7 @@
"dynamic": false,
"info": "The depth of the search.",
"name": "search_depth",
"options": [
"basic",
"advanced"
],
"options": ["basic", "advanced"],
"options_metadata": [],
"placeholder": "",
"required": false,
@ -2165,12 +2036,7 @@
"dynamic": false,
"info": "The time range back from the current date to include in the search results.",
"name": "time_range",
"options": [
"day",
"week",
"month",
"year"
],
"options": ["day", "week", "month", "year"],
"options_metadata": [],
"placeholder": "",
"required": false,
@ -2205,10 +2071,7 @@
"description": "Modify tool names and descriptions to help agents understand when to use each tool.",
"field_parsers": {
"commands": "commands",
"name": [
"snake_case",
"no_blank"
]
"name": ["snake_case", "no_blank"]
},
"hide_options": true
},
@ -2262,16 +2125,12 @@
{
"description": "fetch_content(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.",
"name": "TavilySearchComponent-fetch_content",
"tags": [
"TavilySearchComponent-fetch_content"
]
"tags": ["TavilySearchComponent-fetch_content"]
},
{
"description": "fetch_content_text(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.",
"name": "TavilySearchComponent-fetch_content_text",
"tags": [
"TavilySearchComponent-fetch_content_text"
]
"tags": ["TavilySearchComponent-fetch_content_text"]
}
]
},
@ -2284,10 +2143,7 @@
"dynamic": false,
"info": "The category of the search.",
"name": "topic",
"options": [
"general",
"news"
],
"options": ["general", "news"],
"options_metadata": [],
"placeholder": "",
"required": false,
@ -2321,10 +2177,7 @@
"data": {
"id": "OpenAIModel-prL67",
"node": {
"base_classes": [
"LanguageModel",
"Message"
],
"base_classes": ["LanguageModel", "Message"],
"beta": false,
"category": "models",
"conditional_paths": [],
@ -2363,9 +2216,7 @@
"required_inputs": [],
"selected": "Message",
"tool_mode": true,
"types": [
"Message"
],
"types": ["Message"],
"value": "__UNDEFINED__"
},
{
@ -2374,14 +2225,10 @@
"display_name": "Language Model",
"method": "build_model",
"name": "model_output",
"required_inputs": [
"api_key"
],
"required_inputs": ["api_key"],
"selected": "LanguageModel",
"tool_mode": true,
"types": [
"LanguageModel"
],
"types": ["LanguageModel"],
"value": "__UNDEFINED__"
}
],
@ -2395,9 +2242,7 @@
"display_name": "OpenAI API Key",
"dynamic": false,
"info": "The OpenAI API Key to use for the OpenAI model.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"load_from_db": true,
"name": "api_key",
"password": true,
@ -2432,9 +2277,7 @@
"display_name": "Input",
"dynamic": false,
"info": "",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
@ -2616,9 +2459,7 @@
"display_name": "System Message",
"dynamic": false,
"info": "System message to pass to the model.",
"input_types": [
"Message"
],
"input_types": ["Message"],
"list": false,
"list_add_label": "Add More",
"load_from_db": false,
@ -2714,8 +2555,5 @@
"is_component": false,
"last_tested_version": "1.1.1",
"name": "Market Research",
"tags": [
"assistants",
"agents"
]
}
"tags": ["assistants", "agents"]
}

View file

@ -903,7 +903,7 @@
"stroke": "#555"
},
"className": "stroke-foreground stroke-connection",
"animated": true,
"animated": false,
"id": "reactflow__edge-LLMChain-e2dhNLLMChain|LLMChain-e2dhN|Chain|LLMChain|function|Text-ChatOutput-1jlJyText|message|ChatOutput-1jlJy"
}
],

File diff suppressed because it is too large Load diff

View file

@ -21,6 +21,7 @@ const ExportModal = forwardRef(
const setNoticeData = useAlertStore((state) => state.setNoticeData);
const [checked, setChecked] = useState(false);
const currentFlow = useFlowStore((state) => state.currentFlow);
const isBuilding = useFlowStore((state) => state.isBuilding);
useEffect(() => {
setName(currentFlow?.name ?? "");
setDescription(currentFlow?.description ?? "");
@ -105,7 +106,7 @@ const ExportModal = forwardRef(
</span>
</BaseModal.Content>
<BaseModal.Footer submit={{ label: "Export" }} />
<BaseModal.Footer submit={{ label: "Export", loading: isBuilding }} />
</BaseModal>
);
},

View file

@ -55,7 +55,9 @@ export function checkChatInput(nodes: Node[]) {
}
export function cleanEdges(nodes: AllNodeType[], edges: EdgeType[]) {
let newEdges = cloneDeep(edges);
let newEdges: EdgeType[] = cloneDeep(
edges.map((edge) => ({ ...edge, selected: false, animated: false })),
);
edges.forEach((edge) => {
// check if the source and target node still exists
const sourceNode = nodes.find((node) => node.id === edge.source);