diff --git a/src/backend/base/langflow/base/vectorstores/vector_store_connection_decorator.py b/src/backend/base/langflow/base/vectorstores/vector_store_connection_decorator.py index 411de4955..49cba7ae2 100644 --- a/src/backend/base/langflow/base/vectorstores/vector_store_connection_decorator.py +++ b/src/backend/base/langflow/base/vectorstores/vector_store_connection_decorator.py @@ -34,6 +34,7 @@ def vector_store_connection(cls): hidden=True, name="vectorstoreconnection", method="as_vector_store", + group_outputs=False, ) ] ) diff --git a/src/backend/base/langflow/components/logic/conditional_router.py b/src/backend/base/langflow/components/logic/conditional_router.py index 7709319c2..c6cdec095 100644 --- a/src/backend/base/langflow/components/logic/conditional_router.py +++ b/src/backend/base/langflow/components/logic/conditional_router.py @@ -65,8 +65,8 @@ class ConditionalRouterComponent(Component): ] outputs = [ - Output(display_name="True", name="true_result", method="true_response"), - Output(display_name="False", name="false_result", method="false_response"), + Output(display_name="True", name="true_result", method="true_response", group_outputs=True), + Output(display_name="False", name="false_result", method="false_response", group_outputs=True), ] def _pre_run_setup(self): diff --git a/src/backend/base/langflow/components/logic/loop.py b/src/backend/base/langflow/components/logic/loop.py index 462883e19..2fe5084bf 100644 --- a/src/backend/base/langflow/components/logic/loop.py +++ b/src/backend/base/langflow/components/logic/loop.py @@ -21,8 +21,8 @@ class LoopComponent(Component): ] outputs = [ - Output(display_name="Item", name="item", method="item_output", allows_loop=True), - Output(display_name="Done", name="done", method="done_output"), + Output(display_name="Item", name="item", method="item_output", allows_loop=True, group_outputs=True), + Output(display_name="Done", name="done", method="done_output", group_outputs=True), ] def initialize_data(self) -> None: diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json index 8e6006264..53cccc738 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompt Chaining.json @@ -226,6 +226,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -359,6 +360,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -655,6 +657,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -952,6 +955,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1079,6 +1083,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1296,6 +1301,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1310,6 +1316,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1687,6 +1694,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1701,6 +1709,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -2078,6 +2087,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2092,6 +2102,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json index 65724665b..a8fc05a2a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Basic Prompting.json @@ -118,6 +118,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -401,6 +402,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -604,6 +606,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -917,6 +920,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -931,6 +935,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json index 9e1aa5e92..106dfd2dd 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Blog Writer.json @@ -183,6 +183,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -353,6 +354,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -464,6 +466,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -799,6 +802,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -813,6 +817,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1176,6 +1181,7 @@ "allows_loop": false, "cache": true, "display_name": "Parsed Text", + "group_outputs": false, "method": "parse_combined_text", "name": "parsed_text", "selected": "Message", @@ -1358,6 +1364,7 @@ "allows_loop": false, "cache": true, "display_name": "Result", + "group_outputs": false, "method": "fetch_content", "name": "page_results", "selected": "DataFrame", @@ -1371,6 +1378,7 @@ "allows_loop": false, "cache": true, "display_name": "Raw Result", + "group_outputs": false, "method": "as_message", "name": "raw_results", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Maker.json b/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Maker.json index 8b83f0fa1..f762f9e7f 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Maker.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Custom Component Maker.json @@ -240,6 +240,7 @@ "allows_loop": false, "cache": true, "display_name": "Data", + "group_outputs": false, "method": "retrieve_messages", "name": "messages", "selected": "Data", @@ -253,6 +254,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "retrieve_messages_as_text", "name": "messages_text", "selected": "Message", @@ -266,6 +268,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "selected": "DataFrame", @@ -504,6 +507,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1414,6 +1418,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1428,6 +1433,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1744,6 +1750,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2056,6 +2063,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Diet Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Diet Analysis.json index eca69367a..3abf26486 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Diet Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Diet Analysis.json @@ -126,6 +126,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -436,6 +437,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -574,6 +576,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -588,6 +591,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [], @@ -939,6 +943,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json b/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json index 8abb2343b..358077263 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document Q&A.json @@ -180,6 +180,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -470,6 +471,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -801,6 +803,7 @@ "allows_loop": false, "cache": true, "display_name": "Loaded Files", + "group_outputs": false, "method": "load_dataframe", "name": "dataframe", "required_inputs": [], @@ -1074,6 +1077,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1238,6 +1242,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1252,6 +1257,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json index bd46ba097..f1bd277a4 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Agent.json @@ -349,6 +349,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1373,6 +1374,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1974,6 +1976,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1988,6 +1991,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -3699,6 +3703,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -3875,6 +3880,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json index fdaf1c841..23d133b29 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Financial Report Parser.json @@ -165,6 +165,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -179,6 +180,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -547,6 +549,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -858,6 +861,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1218,6 +1222,7 @@ "allows_loop": false, "cache": true, "display_name": "Structured Output", + "group_outputs": false, "method": "build_structured_output", "name": "structured_output", "selected": "Data", @@ -1231,6 +1236,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "structured_output_dataframe", "selected": "DataFrame", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Gmail Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Gmail Agent.json index 79ec252a7..dd816c435 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Gmail Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Gmail Agent.json @@ -797,6 +797,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1109,6 +1110,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json index 9198e0235..5a4dd38fe 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Hybrid Search RAG.json @@ -268,6 +268,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -578,6 +579,7 @@ "allows_loop": false, "cache": true, "display_name": "Structured Output", + "group_outputs": false, "method": "build_structured_output", "name": "structured_output", "selected": "Data", @@ -591,6 +593,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "structured_output_dataframe", "selected": "DataFrame", @@ -900,6 +903,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -914,6 +918,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1296,6 +1301,7 @@ "allows_loop": false, "cache": true, "display_name": "Search Results", + "group_outputs": false, "method": "search_documents", "name": "search_results", "required_inputs": [ @@ -1314,6 +1320,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "required_inputs": [], @@ -1328,6 +1335,7 @@ "allows_loop": false, "cache": true, "display_name": "Vector Store Connection", + "group_outputs": false, "hidden": true, "method": "as_vector_store", "name": "vectorstoreconnection", @@ -2056,6 +2064,7 @@ "allows_loop": false, "cache": true, "display_name": "Parsed Text", + "group_outputs": false, "method": "parse_combined_text", "name": "parsed_text", "selected": "Message", @@ -2234,6 +2243,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2535,6 +2545,7 @@ "allows_loop": false, "cache": true, "display_name": "Parsed Text", + "group_outputs": false, "method": "parse_combined_text", "name": "parsed_text", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json index fa28a0f74..e2e05e27c 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Image Sentiment Analysis.json @@ -212,6 +212,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -516,6 +517,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -848,6 +850,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -992,6 +995,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1006,6 +1010,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1372,6 +1377,7 @@ "allows_loop": false, "cache": true, "display_name": "Structured Output", + "group_outputs": false, "method": "build_structured_output", "name": "structured_output", "selected": "Data", @@ -1385,6 +1391,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "structured_output_dataframe", "selected": "DataFrame", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json b/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json index 1b8fc7012..0ccae1eda 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Instagram Copywriter.json @@ -326,6 +326,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -619,6 +620,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -788,6 +790,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -898,6 +901,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1053,6 +1057,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1372,6 +1377,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -1974,6 +1980,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -2793,6 +2800,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2807,6 +2815,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -3184,6 +3193,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -3198,6 +3208,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json b/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json index 0d73fd5e6..317dd9089 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Invoice Summarizer.json @@ -183,6 +183,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -311,6 +312,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -874,6 +876,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json index 1c2b37349..11b10fe7e 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json @@ -208,6 +208,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -504,6 +505,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -843,6 +845,7 @@ "allows_loop": false, "cache": true, "display_name": "Structured Output", + "group_outputs": false, "method": "build_structured_output", "name": "structured_output", "selected": "Data", @@ -856,6 +859,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "structured_output_dataframe", "selected": "DataFrame", @@ -1223,6 +1227,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -2302,6 +2307,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2316,6 +2322,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json b/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json index ecfccca9b..676d739b5 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Meeting Summary.json @@ -317,6 +317,7 @@ "allows_loop": false, "cache": true, "display_name": "Transcription Result", + "group_outputs": false, "method": "poll_transcription_job", "name": "transcription_result", "selected": "Data", @@ -478,6 +479,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -492,6 +494,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -859,6 +862,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1009,6 +1013,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1310,6 +1315,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1621,6 +1627,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1635,6 +1642,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -2001,6 +2009,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2304,6 +2313,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -2474,6 +2484,7 @@ "allows_loop": false, "cache": true, "display_name": "Data", + "group_outputs": false, "method": "retrieve_messages", "name": "messages", "selected": "Data", @@ -2487,6 +2498,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "retrieve_messages_as_text", "name": "messages_text", "selected": "Message", @@ -2500,6 +2512,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "selected": "DataFrame", @@ -2741,6 +2754,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -3154,6 +3168,7 @@ "allows_loop": false, "cache": true, "display_name": "Transcript ID", + "group_outputs": false, "method": "create_transcription_job", "name": "transcript_id", "selected": "Data", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index b34c69ae2..4abb4dea3 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -150,6 +150,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -454,6 +455,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -821,6 +823,7 @@ "allows_loop": false, "cache": true, "display_name": "Data", + "group_outputs": false, "method": "retrieve_messages", "name": "messages", "selected": "Data", @@ -834,6 +837,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "retrieve_messages_as_text", "name": "messages_text", "selected": "Message", @@ -847,6 +851,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "selected": "DataFrame", @@ -1085,6 +1090,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1250,6 +1256,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1264,6 +1271,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json index 8df3bc9d6..c77f9a6b9 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json @@ -616,6 +616,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -943,6 +944,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -1642,6 +1644,7 @@ "allows_loop": false, "cache": true, "display_name": "Confirmation", + "group_outputs": false, "method": "save_to_file", "name": "confirmation", "selected": "Text", @@ -1800,6 +1803,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json index 555ec8c80..0dade55e7 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Pokédex Agent.json @@ -125,6 +125,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -437,6 +438,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json index fc0c87ac5..8788b46f6 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Portfolio Website Code Generator.json @@ -234,6 +234,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -357,6 +358,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -371,6 +373,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -697,6 +700,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -711,6 +715,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1028,6 +1033,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1479,6 +1485,7 @@ "allows_loop": false, "cache": true, "display_name": "Structured Output", + "group_outputs": false, "method": "build_structured_output", "name": "structured_output", "selected": "Data", @@ -1492,6 +1499,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "structured_output_dataframe", "selected": "DataFrame", @@ -1848,6 +1856,7 @@ "allows_loop": false, "cache": true, "display_name": "Loaded Files", + "group_outputs": false, "method": "load_dataframe", "name": "dataframe", "required_inputs": [], @@ -2126,6 +2135,7 @@ "allows_loop": false, "cache": true, "display_name": "Parsed Text", + "group_outputs": false, "method": "parse_combined_text", "name": "parsed_text", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json index 2c260c471..20a80bf3d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json @@ -156,6 +156,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -467,6 +468,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1652,6 +1654,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json index a9023bcbf..4d17adcb8 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Research Agent.json @@ -322,6 +322,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -478,6 +479,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -771,6 +773,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1004,6 +1007,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -1603,6 +1607,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1730,6 +1735,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -2369,6 +2375,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2383,6 +2390,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -2760,6 +2768,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2774,6 +2783,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -3142,6 +3152,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json b/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json index d44ff4691..820fde606 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json @@ -234,6 +234,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "search_papers_dataframe", "name": "dataframe", "selected": "DataFrame", @@ -399,6 +400,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -413,6 +415,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -722,6 +725,7 @@ "allows_loop": false, "cache": true, "display_name": "Data", + "group_outputs": false, "method": "convert_message_to_data", "name": "data", "selected": "Data", @@ -833,6 +837,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1142,6 +1147,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1503,6 +1509,7 @@ "allows_loop": false, "cache": true, "display_name": "Parsed Text", + "group_outputs": false, "method": "parse_combined_text", "name": "parsed_text", "selected": "Message", @@ -1676,6 +1683,7 @@ "allows_loop": true, "cache": true, "display_name": "Item", + "group_outputs": true, "method": "item_output", "name": "item", "selected": "Data", @@ -1689,6 +1697,7 @@ "allows_loop": false, "cache": true, "display_name": "Done", + "group_outputs": true, "method": "done_output", "name": "done", "selected": "DataFrame", @@ -1719,7 +1728,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from langflow.custom import Component\nfrom langflow.io import HandleInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.dataframe import DataFrame\n\n\nclass LoopComponent(Component):\n display_name = \"Loop\"\n description = (\n \"Iterates over a list of Data objects, outputting one item at a time and aggregating results from loop inputs.\"\n )\n icon = \"infinity\"\n\n inputs = [\n HandleInput(\n name=\"data\",\n display_name=\"Data or DataFrame\",\n info=\"The initial list of Data objects or DataFrame to iterate over.\",\n input_types=[\"Data\", \"DataFrame\"],\n ),\n ]\n\n outputs = [\n Output(display_name=\"Item\", name=\"item\", method=\"item_output\", allows_loop=True),\n Output(display_name=\"Done\", name=\"done\", method=\"done_output\"),\n ]\n\n def initialize_data(self) -> None:\n \"\"\"Initialize the data list, context index, and aggregated list.\"\"\"\n if self.ctx.get(f\"{self._id}_initialized\", False):\n return\n\n # Ensure data is a list of Data objects\n data_list = self._validate_data(self.data)\n\n # Store the initial data and context variables\n self.update_ctx(\n {\n f\"{self._id}_data\": data_list,\n f\"{self._id}_index\": 0,\n f\"{self._id}_aggregated\": [],\n f\"{self._id}_initialized\": True,\n }\n )\n\n def _validate_data(self, data):\n \"\"\"Validate and return a list of Data objects.\"\"\"\n if isinstance(data, DataFrame):\n return data.to_data_list()\n if isinstance(data, Data):\n return [data]\n if isinstance(data, list) and all(isinstance(item, Data) for item in data):\n return data\n msg = \"The 'data' input must be a DataFrame, a list of Data objects, or a single Data object.\"\n raise TypeError(msg)\n\n def evaluate_stop_loop(self) -> bool:\n \"\"\"Evaluate whether to stop item or done output.\"\"\"\n current_index = self.ctx.get(f\"{self._id}_index\", 0)\n data_length = len(self.ctx.get(f\"{self._id}_data\", []))\n return current_index > data_length\n\n def item_output(self) -> Data:\n \"\"\"Output the next item in the list or stop if done.\"\"\"\n self.initialize_data()\n current_item = Data(text=\"\")\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n return Data(text=\"\")\n\n # Get data list and current index\n data_list, current_index = self.loop_variables()\n if current_index < len(data_list):\n # Output current item and increment index\n try:\n current_item = data_list[current_index]\n except IndexError:\n current_item = Data(text=\"\")\n self.aggregated_output()\n self.update_ctx({f\"{self._id}_index\": current_index + 1})\n return current_item\n\n def done_output(self) -> DataFrame:\n \"\"\"Trigger the done output when iteration is complete.\"\"\"\n self.initialize_data()\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n self.start(\"done\")\n\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n\n return DataFrame(aggregated)\n self.stop(\"done\")\n return DataFrame([])\n\n def loop_variables(self):\n \"\"\"Retrieve loop variables from context.\"\"\"\n return (\n self.ctx.get(f\"{self._id}_data\", []),\n self.ctx.get(f\"{self._id}_index\", 0),\n )\n\n def aggregated_output(self) -> list[Data]:\n \"\"\"Return the aggregated list once all items are processed.\"\"\"\n self.initialize_data()\n\n # Get data list and aggregated list\n data_list = self.ctx.get(f\"{self._id}_data\", [])\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n loop_input = self.item\n if loop_input is not None and not isinstance(loop_input, str) and len(aggregated) <= len(data_list):\n aggregated.append(loop_input)\n self.update_ctx({f\"{self._id}_aggregated\": aggregated})\n return aggregated\n" + "value": "from langflow.custom import Component\nfrom langflow.io import HandleInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.dataframe import DataFrame\n\n\nclass LoopComponent(Component):\n display_name = \"Loop\"\n description = (\n \"Iterates over a list of Data objects, outputting one item at a time and aggregating results from loop inputs.\"\n )\n icon = \"infinity\"\n\n inputs = [\n HandleInput(\n name=\"data\",\n display_name=\"Data or DataFrame\",\n info=\"The initial list of Data objects or DataFrame to iterate over.\",\n input_types=[\"Data\", \"DataFrame\"],\n ),\n ]\n\n outputs = [\n Output(display_name=\"Item\", name=\"item\", method=\"item_output\", allows_loop=True, group_outputs=True),\n Output(display_name=\"Done\", name=\"done\", method=\"done_output\", group_outputs=True),\n ]\n\n def initialize_data(self) -> None:\n \"\"\"Initialize the data list, context index, and aggregated list.\"\"\"\n if self.ctx.get(f\"{self._id}_initialized\", False):\n return\n\n # Ensure data is a list of Data objects\n data_list = self._validate_data(self.data)\n\n # Store the initial data and context variables\n self.update_ctx(\n {\n f\"{self._id}_data\": data_list,\n f\"{self._id}_index\": 0,\n f\"{self._id}_aggregated\": [],\n f\"{self._id}_initialized\": True,\n }\n )\n\n def _validate_data(self, data):\n \"\"\"Validate and return a list of Data objects.\"\"\"\n if isinstance(data, DataFrame):\n return data.to_data_list()\n if isinstance(data, Data):\n return [data]\n if isinstance(data, list) and all(isinstance(item, Data) for item in data):\n return data\n msg = \"The 'data' input must be a DataFrame, a list of Data objects, or a single Data object.\"\n raise TypeError(msg)\n\n def evaluate_stop_loop(self) -> bool:\n \"\"\"Evaluate whether to stop item or done output.\"\"\"\n current_index = self.ctx.get(f\"{self._id}_index\", 0)\n data_length = len(self.ctx.get(f\"{self._id}_data\", []))\n return current_index > data_length\n\n def item_output(self) -> Data:\n \"\"\"Output the next item in the list or stop if done.\"\"\"\n self.initialize_data()\n current_item = Data(text=\"\")\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n return Data(text=\"\")\n\n # Get data list and current index\n data_list, current_index = self.loop_variables()\n if current_index < len(data_list):\n # Output current item and increment index\n try:\n current_item = data_list[current_index]\n except IndexError:\n current_item = Data(text=\"\")\n self.aggregated_output()\n self.update_ctx({f\"{self._id}_index\": current_index + 1})\n return current_item\n\n def done_output(self) -> DataFrame:\n \"\"\"Trigger the done output when iteration is complete.\"\"\"\n self.initialize_data()\n\n if self.evaluate_stop_loop():\n self.stop(\"item\")\n self.start(\"done\")\n\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n\n return DataFrame(aggregated)\n self.stop(\"done\")\n return DataFrame([])\n\n def loop_variables(self):\n \"\"\"Retrieve loop variables from context.\"\"\"\n return (\n self.ctx.get(f\"{self._id}_data\", []),\n self.ctx.get(f\"{self._id}_index\", 0),\n )\n\n def aggregated_output(self) -> list[Data]:\n \"\"\"Return the aggregated list once all items are processed.\"\"\"\n self.initialize_data()\n\n # Get data list and aggregated list\n data_list = self.ctx.get(f\"{self._id}_data\", [])\n aggregated = self.ctx.get(f\"{self._id}_aggregated\", [])\n loop_input = self.item\n if loop_input is not None and not isinstance(loop_input, str) and len(aggregated) <= len(data_list):\n aggregated.append(loop_input)\n self.update_ctx({f\"{self._id}_aggregated\": aggregated})\n return aggregated\n" }, "data": { "_input_type": "HandleInput", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json index 2453863cf..1bcb48865 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SEO Keyword Generator.json @@ -128,6 +128,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -428,6 +429,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -561,6 +563,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -904,6 +907,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -918,6 +922,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json index 49d7d20cb..d08ef0b89 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json @@ -123,6 +123,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -371,6 +372,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -726,6 +728,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json index 69f783202..8e7bbae00 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Search agent.json @@ -343,6 +343,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -652,6 +653,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json index c5b9b7e39..f1abeb9ac 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Sequential Tasks Agents.json @@ -370,6 +370,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -992,6 +993,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -1597,6 +1599,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1730,6 +1733,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1866,6 +1870,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -2043,6 +2048,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2436,6 +2442,7 @@ "allows_loop": false, "cache": true, "display_name": "Response", + "group_outputs": false, "method": "message_response", "name": "response", "selected": "Message", @@ -4064,6 +4071,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json index 8eff35cbf..b4fde9288 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json @@ -602,6 +602,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -915,6 +916,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json index 1362ade86..1182c2393 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Social Media Agent.json @@ -642,6 +642,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -952,6 +953,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json index bbbc144de..4a2c45373 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Text Sentiment Analysis.json @@ -265,6 +265,7 @@ "allows_loop": false, "cache": true, "display_name": "Loaded Files", + "group_outputs": false, "method": "load_dataframe", "name": "dataframe", "required_inputs": [], @@ -549,6 +550,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -702,6 +704,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -864,6 +867,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -878,6 +882,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1255,6 +1260,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1269,6 +1275,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1635,6 +1642,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1775,6 +1783,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1789,6 +1798,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -2182,6 +2192,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2489,6 +2500,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json index 4b7cdff91..83cc967c1 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json @@ -232,6 +232,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -528,6 +529,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json b/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json index 20af0fc53..89d8a448b 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Twitter Thread Generator.json @@ -296,6 +296,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -582,6 +583,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -696,6 +698,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -989,6 +992,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -1093,6 +1097,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -1197,6 +1202,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -1301,6 +1307,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -1405,6 +1412,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text", "selected": "Message", @@ -1557,6 +1565,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -1838,6 +1847,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -1852,6 +1862,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 31ff40999..9a99d4676 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -325,6 +325,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -617,6 +618,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -789,6 +791,7 @@ "allows_loop": false, "cache": true, "display_name": "Chunks", + "group_outputs": false, "method": "split_text", "name": "chunks", "selected": "Data", @@ -802,6 +805,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "selected": "DataFrame", @@ -1085,6 +1089,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -1398,6 +1403,7 @@ "allows_loop": false, "cache": true, "display_name": "Embeddings", + "group_outputs": false, "method": "build_embeddings", "name": "embeddings", "required_inputs": [ @@ -1932,6 +1938,7 @@ "allows_loop": false, "cache": true, "display_name": "Embeddings", + "group_outputs": false, "method": "build_embeddings", "name": "embeddings", "required_inputs": [ @@ -2412,6 +2419,7 @@ "allows_loop": false, "cache": true, "display_name": "Loaded Files", + "group_outputs": false, "method": "load_dataframe", "name": "dataframe", "required_inputs": [], @@ -2790,6 +2798,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -2804,6 +2813,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -3359,6 +3369,7 @@ "allows_loop": false, "cache": true, "display_name": "Search Results", + "group_outputs": false, "method": "search_documents", "name": "search_results", "required_inputs": [ @@ -3377,6 +3388,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "required_inputs": [], @@ -3391,6 +3403,7 @@ "allows_loop": false, "cache": true, "display_name": "Vector Store Connection", + "group_outputs": false, "hidden": true, "method": "as_vector_store", "name": "vectorstoreconnection", @@ -4118,6 +4131,7 @@ "allows_loop": false, "cache": true, "display_name": "Search Results", + "group_outputs": false, "method": "search_documents", "name": "search_results", "required_inputs": [ @@ -4136,6 +4150,7 @@ "allows_loop": false, "cache": true, "display_name": "DataFrame", + "group_outputs": false, "method": "as_dataframe", "name": "dataframe", "required_inputs": [], @@ -4150,6 +4165,7 @@ "allows_loop": false, "cache": true, "display_name": "Vector Store Connection", + "group_outputs": false, "hidden": true, "method": "as_vector_store", "name": "vectorstoreconnection", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json index e9d784437..7e2c37d3b 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json @@ -346,6 +346,7 @@ "allows_loop": false, "cache": true, "display_name": "LLM Results", + "group_outputs": false, "method": "run_batch", "name": "batch_results", "selected": "DataFrame", @@ -559,6 +560,7 @@ "allows_loop": false, "cache": true, "display_name": "Comments", + "group_outputs": false, "method": "get_video_comments", "name": "comments", "selected": "DataFrame", @@ -776,6 +778,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "text_response", "name": "text_output", "required_inputs": [], @@ -790,6 +793,7 @@ "allows_loop": false, "cache": true, "display_name": "Language Model", + "group_outputs": false, "method": "build_model", "name": "model_output", "required_inputs": [ @@ -1826,6 +1830,7 @@ "allows_loop": false, "cache": true, "display_name": "Prompt", + "group_outputs": false, "method": "build_prompt", "name": "prompt", "selected": "Message", @@ -2000,6 +2005,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2591,6 +2597,7 @@ "allows_loop": false, "cache": true, "display_name": "Message", + "group_outputs": false, "method": "message_response", "name": "message", "selected": "Message", @@ -2988,6 +2995,7 @@ "allows_loop": false, "cache": true, "display_name": "True", + "group_outputs": true, "method": "true_response", "name": "true_result", "selected": "Message", @@ -3001,6 +3009,7 @@ "allows_loop": false, "cache": true, "display_name": "False", + "group_outputs": true, "method": "false_response", "name": "false_result", "selected": "Message", @@ -3049,7 +3058,7 @@ "show": true, "title_case": false, "type": "code", - "value": "import re\n\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ConditionalRouterComponent(Component):\n display_name = \"If-Else\"\n description = \"Routes an input message to a corresponding output based on text comparison.\"\n icon = \"split\"\n name = \"ConditionalRouter\"\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.__iteration_updated = False\n\n inputs = [\n MessageTextInput(\n name=\"input_text\",\n display_name=\"Text Input\",\n info=\"The primary text input for the operation.\",\n required=True,\n ),\n MessageTextInput(\n name=\"match_text\",\n display_name=\"Match Text\",\n info=\"The text input to compare against.\",\n required=True,\n ),\n DropdownInput(\n name=\"operator\",\n display_name=\"Operator\",\n options=[\"equals\", \"not equals\", \"contains\", \"starts with\", \"ends with\", \"regex\"],\n info=\"The operator to apply for comparing the texts.\",\n value=\"equals\",\n real_time_refresh=True,\n ),\n BoolInput(\n name=\"case_sensitive\",\n display_name=\"Case Sensitive\",\n info=\"If true, the comparison will be case sensitive.\",\n value=False,\n ),\n MessageInput(\n name=\"message\",\n display_name=\"Message\",\n info=\"The message to pass through either route.\",\n ),\n IntInput(\n name=\"max_iterations\",\n display_name=\"Max Iterations\",\n info=\"The maximum number of iterations for the conditional router.\",\n value=10,\n advanced=True,\n ),\n DropdownInput(\n name=\"default_route\",\n display_name=\"Default Route\",\n options=[\"true_result\", \"false_result\"],\n info=\"The default route to take when max iterations are reached.\",\n value=\"false_result\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"True\", name=\"true_result\", method=\"true_response\"),\n Output(display_name=\"False\", name=\"false_result\", method=\"false_response\"),\n ]\n\n def _pre_run_setup(self):\n self.__iteration_updated = False\n\n def evaluate_condition(self, input_text: str, match_text: str, operator: str, *, case_sensitive: bool) -> bool:\n if not case_sensitive and operator != \"regex\":\n input_text = input_text.lower()\n match_text = match_text.lower()\n\n if operator == \"equals\":\n return input_text == match_text\n if operator == \"not equals\":\n return input_text != match_text\n if operator == \"contains\":\n return match_text in input_text\n if operator == \"starts with\":\n return input_text.startswith(match_text)\n if operator == \"ends with\":\n return input_text.endswith(match_text)\n if operator == \"regex\":\n try:\n return bool(re.match(match_text, input_text))\n except re.error:\n return False # Return False if the regex is invalid\n return False\n\n def iterate_and_stop_once(self, route_to_stop: str):\n if not self.__iteration_updated:\n self.update_ctx({f\"{self._id}_iteration\": self.ctx.get(f\"{self._id}_iteration\", 0) + 1})\n self.__iteration_updated = True\n if self.ctx.get(f\"{self._id}_iteration\", 0) >= self.max_iterations and route_to_stop == self.default_route:\n route_to_stop = \"true_result\" if route_to_stop == \"false_result\" else \"false_result\"\n self.stop(route_to_stop)\n\n def true_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if result:\n self.status = self.message\n self.iterate_and_stop_once(\"false_result\")\n return self.message\n self.iterate_and_stop_once(\"true_result\")\n return Message(content=\"\")\n\n def false_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if not result:\n self.status = self.message\n self.iterate_and_stop_once(\"true_result\")\n return self.message\n self.iterate_and_stop_once(\"false_result\")\n return Message(content=\"\")\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n if field_name == \"operator\":\n if field_value == \"regex\":\n build_config.pop(\"case_sensitive\", None)\n\n # Ensure case_sensitive is present for all other operators\n elif \"case_sensitive\" not in build_config:\n case_sensitive_input = next(\n (input_field for input_field in self.inputs if input_field.name == \"case_sensitive\"), None\n )\n if case_sensitive_input:\n build_config[\"case_sensitive\"] = case_sensitive_input.to_dict()\n return build_config\n" + "value": "import re\n\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ConditionalRouterComponent(Component):\n display_name = \"If-Else\"\n description = \"Routes an input message to a corresponding output based on text comparison.\"\n icon = \"split\"\n name = \"ConditionalRouter\"\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.__iteration_updated = False\n\n inputs = [\n MessageTextInput(\n name=\"input_text\",\n display_name=\"Text Input\",\n info=\"The primary text input for the operation.\",\n required=True,\n ),\n MessageTextInput(\n name=\"match_text\",\n display_name=\"Match Text\",\n info=\"The text input to compare against.\",\n required=True,\n ),\n DropdownInput(\n name=\"operator\",\n display_name=\"Operator\",\n options=[\"equals\", \"not equals\", \"contains\", \"starts with\", \"ends with\", \"regex\"],\n info=\"The operator to apply for comparing the texts.\",\n value=\"equals\",\n real_time_refresh=True,\n ),\n BoolInput(\n name=\"case_sensitive\",\n display_name=\"Case Sensitive\",\n info=\"If true, the comparison will be case sensitive.\",\n value=False,\n ),\n MessageInput(\n name=\"message\",\n display_name=\"Message\",\n info=\"The message to pass through either route.\",\n ),\n IntInput(\n name=\"max_iterations\",\n display_name=\"Max Iterations\",\n info=\"The maximum number of iterations for the conditional router.\",\n value=10,\n advanced=True,\n ),\n DropdownInput(\n name=\"default_route\",\n display_name=\"Default Route\",\n options=[\"true_result\", \"false_result\"],\n info=\"The default route to take when max iterations are reached.\",\n value=\"false_result\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"True\", name=\"true_result\", method=\"true_response\", group_outputs=True),\n Output(display_name=\"False\", name=\"false_result\", method=\"false_response\", group_outputs=True),\n ]\n\n def _pre_run_setup(self):\n self.__iteration_updated = False\n\n def evaluate_condition(self, input_text: str, match_text: str, operator: str, *, case_sensitive: bool) -> bool:\n if not case_sensitive and operator != \"regex\":\n input_text = input_text.lower()\n match_text = match_text.lower()\n\n if operator == \"equals\":\n return input_text == match_text\n if operator == \"not equals\":\n return input_text != match_text\n if operator == \"contains\":\n return match_text in input_text\n if operator == \"starts with\":\n return input_text.startswith(match_text)\n if operator == \"ends with\":\n return input_text.endswith(match_text)\n if operator == \"regex\":\n try:\n return bool(re.match(match_text, input_text))\n except re.error:\n return False # Return False if the regex is invalid\n return False\n\n def iterate_and_stop_once(self, route_to_stop: str):\n if not self.__iteration_updated:\n self.update_ctx({f\"{self._id}_iteration\": self.ctx.get(f\"{self._id}_iteration\", 0) + 1})\n self.__iteration_updated = True\n if self.ctx.get(f\"{self._id}_iteration\", 0) >= self.max_iterations and route_to_stop == self.default_route:\n route_to_stop = \"true_result\" if route_to_stop == \"false_result\" else \"false_result\"\n self.stop(route_to_stop)\n\n def true_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if result:\n self.status = self.message\n self.iterate_and_stop_once(\"false_result\")\n return self.message\n self.iterate_and_stop_once(\"true_result\")\n return Message(content=\"\")\n\n def false_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if not result:\n self.status = self.message\n self.iterate_and_stop_once(\"true_result\")\n return self.message\n self.iterate_and_stop_once(\"false_result\")\n return Message(content=\"\")\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n if field_name == \"operator\":\n if field_value == \"regex\":\n build_config.pop(\"case_sensitive\", None)\n\n # Ensure case_sensitive is present for all other operators\n elif \"case_sensitive\" not in build_config:\n case_sensitive_input = next(\n (input_field for input_field in self.inputs if input_field.name == \"case_sensitive\"), None\n )\n if case_sensitive_input:\n build_config[\"case_sensitive\"] = case_sensitive_input.to_dict()\n return build_config\n" }, "default_route": { "_input_type": "DropdownInput", diff --git a/src/backend/base/langflow/template/field/base.py b/src/backend/base/langflow/template/field/base.py index 6c66ce465..41775c59c 100644 --- a/src/backend/base/langflow/template/field/base.py +++ b/src/backend/base/langflow/template/field/base.py @@ -208,6 +208,9 @@ class Output(BaseModel): allows_loop: bool = Field(default=False) """Specifies if the output allows looping.""" + group_outputs: bool = Field(default=False) + """Specifies if all outputs should be grouped and shown without dropdowns.""" + options: OutputOptions | None = Field(default=None) """Options for the output.""" diff --git a/src/backend/tests/unit/test_schema.py b/src/backend/tests/unit/test_schema.py index 72c8b4571..4f8a1ca9f 100644 --- a/src/backend/tests/unit/test_schema.py +++ b/src/backend/tests/unit/test_schema.py @@ -139,6 +139,7 @@ class TestOutput: "types": [], "name": "test_output", "display_name": "test_output", + "group_outputs": False, "cache": True, "value": "__UNDEFINED__", "tool_mode": True, diff --git a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputParameter/NodeOutputs.tsx b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputParameter/NodeOutputs.tsx index 19b48cc44..3edd38500 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputParameter/NodeOutputs.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputParameter/NodeOutputs.tsx @@ -1,4 +1,3 @@ -// NodeOutputs.tsx import { NodeDataType } from "@/types/flow"; import { OutputParameter } from "."; @@ -25,80 +24,86 @@ export default function NodeOutputs({ selectedOutput: any; handleSelectOutput: any; }) { - const output = selectedOutput - ? outputs.find((output) => output.name === selectedOutput.name) - : outputs[0]; + const hasLoopOutput = outputs.some((output) => output.allows_loop); + const hasGroupOutputs = outputs.some((output) => output.group_outputs); + const isConditionalRouter = data.type === "ConditionalRouter"; + const hasHiddenOutputs = outputs.some((output) => output.hidden); - if (!output) return null; + const shouldShowAllOutputs = + hasLoopOutput || hasGroupOutputs || isConditionalRouter || hasHiddenOutputs; - const idx = - data.node!.outputs?.findIndex((out) => out.name === output.name) ?? 0; + if (shouldShowAllOutputs) { + const outputsToRender = + keyPrefix === "hidden" + ? outputs.filter((output) => output.hidden) + : outputs.filter((output) => !output.hidden); - const isLoop = output?.allows_loop ?? false; + return ( + <> + {outputsToRender?.map((output, idx) => ( + out.name === output.name, + ) ?? idx + } + lastOutput={idx === outputsToRender.length - 1} + data={data} + types={types} + selected={selected} + showNode={showNode} + isToolMode={isToolMode} + showHiddenOutputs={showHiddenOutputs} + handleSelectOutput={handleSelectOutput} + hidden={ + keyPrefix === "hidden" + ? showHiddenOutputs + ? output.hidden + : true + : false + } + /> + ))} + + ); + } - const hiddenOutputs = outputs.filter((output) => output.hidden); + const getDisplayOutput = () => { + const filteredOutputs = + keyPrefix === "hidden" + ? outputs.filter((output) => output.hidden) + : outputs.filter((output) => !output.hidden); - return isLoop ? ( - keyPrefix === "hidden" ? ( - hiddenOutputs?.map((output, idx) => ( - out.name === output.name) ?? - idx - } - lastOutput={idx === outputs.length - 1} - data={data} - types={types} - selected={selected} - showNode={showNode} - isToolMode={isToolMode} - showHiddenOutputs={showHiddenOutputs} - handleSelectOutput={handleSelectOutput} - hidden={ - keyPrefix === "hidden" - ? showHiddenOutputs - ? output.hidden - : true - : false - } - /> - )) - ) : ( - outputs?.map((output, idx) => ( - out.name === output.name) ?? - idx - } - lastOutput={idx === outputs.length - 1} - data={data} - types={types} - selected={selected} - showNode={showNode} - isToolMode={isToolMode} - showHiddenOutputs={showHiddenOutputs} - handleSelectOutput={handleSelectOutput} - hidden={ - keyPrefix === "hidden" - ? showHiddenOutputs - ? output.hidden - : true - : false - } - /> - )) - ) - ) : ( + if (selectedOutput) { + return ( + filteredOutputs.find((output) => output.name === selectedOutput.name) || + filteredOutputs[0] + ); + } + + const outputWithSelection = filteredOutputs.find( + (output) => output.selected, + ); + + return outputWithSelection || filteredOutputs[0]; + }; + + const displayOutput = getDisplayOutput(); + + if (!displayOutput) return null; + + return ( out.name === output.name) ?? idx + data.node!.outputs?.findIndex( + (out) => out.name === displayOutput.name, + ) ?? 0 } lastOutput={true} data={data} @@ -111,7 +116,7 @@ export default function NodeOutputs({ hidden={ keyPrefix === "hidden" ? showHiddenOutputs - ? output.hidden + ? displayOutput.hidden : true : false } diff --git a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx index d391562e4..a83d347ea 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/NodeOutputfield/index.tsx @@ -38,7 +38,6 @@ import OutputComponent from "../OutputComponent"; import HandleRenderComponent from "../handleRenderComponent"; import OutputModal from "../outputModal"; -// Memoize IconComponent instances const EyeIcon = memo( ({ hidden, className }: { hidden: boolean; className: string }) => ( ( )); -// Memoize Button components const HideShowButton = memo( ({ disabled, @@ -178,14 +176,12 @@ function NodeOutputField({ const ref = useRef(null); const updateNodeInternals = useUpdateNodeInternals(); - // Use selective store subscriptions const edges = useFlowStore((state) => state.edges); const setNode = useFlowStore((state) => state.setNode); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const flowPool = useFlowStore((state) => state.flowPool); const myData = useTypesStore((state) => state.data); - // Memoize computed values const { flowPoolId, internalOutputName } = useMemo(() => { if (data.node?.flow && outputProxy) { const realOutput = getGroupOutputNodeId( @@ -450,9 +446,7 @@ function NodeOutputField({ errorOutput={errorOutput ?? false} isToolMode={isToolMode} title={title} - onClick={() => { - //just to trigger the memoization - }} + onClick={() => {}} id={data?.type} /> diff --git a/src/frontend/src/CustomNodes/GenericNode/components/OutputComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/OutputComponent/index.tsx index bcf0d44c1..c12669d2f 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/OutputComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/OutputComponent/index.tsx @@ -6,6 +6,7 @@ import { DropdownMenuItem, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; +import useFlowStore from "@/stores/flowStore"; import ShadTooltip from "../../../../components/common/shadTooltipComponent"; import { outputComponentType } from "../../../../types/components"; import { cn } from "../../../../utils/utils"; @@ -23,6 +24,10 @@ export default function OutputComponent({ handleSelectOutput, outputName, }: outputComponentType) { + const nodeType = useFlowStore( + (state) => state.nodes.find((node) => node.id === nodeId)?.data?.type, + ); + const displayProxy = (children) => { if (proxy) { return ( @@ -47,9 +52,17 @@ export default function OutputComponent({ , ); + const hasLoopOutput = outputs?.some?.((output) => output.allows_loop); + const hasGroupOutputs = outputs?.some?.((output) => output.group_outputs); + const isConditionalRouter = nodeType === "ConditionalRouter"; + const hasOutputs = outputs.length > 1; + + const shouldShowDropdown = + hasOutputs && !hasLoopOutput && !hasGroupOutputs && !isConditionalRouter; + return (
- {outputs.length > 1 ? ( + {shouldShowDropdown ? ( - // - // - // {types.map((type) => ( - // { - // // TODO: UDPDATE SET NODE TO NEW NODE FORM - // setNode(nodeId, (node) => { - // const newNode = cloneDeep(node); - // (newNode.data as NodeDataType).node!.outputs![idx].selected = - // type; - // return newNode; - // }); - // updateNodeInternals(nodeId); - // }} - // > - // {type} - // - // ))} - // - // - // {proxy ? ( - // {proxy.nodeDisplayName}}> - // {name} - // - // ) : ( - // {name} - // )} - //
- // ); } diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx index 8c05138c5..d7432d52d 100644 --- a/src/frontend/src/CustomNodes/GenericNode/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx @@ -54,13 +54,12 @@ const HiddenOutputsButton = memo( }) => ( ), @@ -219,7 +218,6 @@ function GenericNode({ const update = useShortcutsStore((state) => state.update); useHotkeys(update, handleUpdateCodeWShortcut, { preventDefault: true }); - // Memoized values const isToolMode = useMemo( () => data.node?.outputs?.some( @@ -261,35 +259,47 @@ function GenericNode({ }, [data.node?.outputs]); const [selectedOutput, setSelectedOutput] = useState( - null, + () => data.node?.outputs?.find((output) => output.selected) || null, ); const handleSelectOutput = useCallback( (output) => { setSelectedOutput(output); - // Remove any edges connected to this output handle - const sourceHandleId = scapedJSONStringfy({ - output_types: [output.selected ?? output.types[0]], - id: data.id, - dataType: data.type, - name: output.name, - }); - setEdges((eds) => - eds.filter((edge) => edge.sourceHandle !== sourceHandleId), - ); + setEdges((eds) => { + return eds.map((edge) => { + if (edge.source === data.id && edge.data?.sourceHandle) { + const sourceHandle = edge.data.sourceHandle; + if (sourceHandle.name === output.name) { + const newSourceHandle = { + ...sourceHandle, + output_types: [output.selected ?? output.types[0]], + }; + const newSourceHandleId = scapedJSONStringfy(newSourceHandle); + + return { + ...edge, + sourceHandle: newSourceHandleId, + data: { + ...edge.data, + sourceHandle: newSourceHandle, + }, + }; + } + } + return edge; + }); + }); setNode(data.id, (oldNode) => { const newNode = cloneDeep(oldNode); if (newNode.data.node?.outputs) { - // First, clear any previous selections newNode.data.node.outputs.forEach((out) => { if (out.selected) { out.selected = undefined; } }); - // Then set the new selection const outputIndex = newNode.data.node.outputs.findIndex( (o) => o.name === output.name, ); @@ -566,38 +576,32 @@ function GenericNode({ > {" "} - {!showHiddenOutputs && shownOutputs && ( + + {showHiddenOutputs && ( )} -
-
- -
-
{hiddenOutputs && hiddenOutputs.length > 0 && ( checkHasToolMode(data.node?.template ?? {}) && !isGroup, [data.node?.template, isGroup], diff --git a/src/frontend/tests/core/integrations/decisionFlow.spec.ts b/src/frontend/tests/core/integrations/decisionFlow.spec.ts index a517c3387..6d0d11738 100644 --- a/src/frontend/tests/core/integrations/decisionFlow.spec.ts +++ b/src/frontend/tests/core/integrations/decisionFlow.spec.ts @@ -322,12 +322,6 @@ test( .getByTestId("handle-pass-shownode-ignored message-left") .nth(1) .click(); - - await page.getByTestId("dropdown-output-conditionalrouter").click(); - await page - .getByTestId("dropdown-item-output-conditionalrouter-false") - .click(); - await page .getByTestId("handle-conditionalrouter-shownode-false-right") .nth(0)