refactor(tests): parameterize template tests and update timeout use (#9224)

* refactor: Simplify flow execution validation by removing unnecessary asyncio.wait_for calls

Updated the validate_flow_execution function to directly use the client.post and client.get methods with a timeout parameter, improving code readability and maintainability. This change eliminates redundant timeout handling while ensuring consistent timeout values across API calls.

* refactor: Enhance template tests for improved structure and validation

Refactored the template tests in `test_starter_projects.py` to utilize parameterization for better readability and maintainability. Introduced helper functions to retrieve template files and disabled tracing for all tests. Updated individual test methods to validate JSON structure, flow execution, and endpoint validation, ensuring comprehensive coverage of template functionality. This change streamlines the testing process and enhances the robustness of the test suite.

* refactor: Update project metadata and import paths in starter project JSON files

Modified the metadata section in multiple starter project JSON files to reflect updated code hashes and module paths, transitioning from 'lfx' to 'langflow' components. This change enhances consistency across the codebase and ensures that the correct modules are referenced for improved maintainability and clarity.

* chore: Update template test commands to utilize parallel execution

Modified the commands in the Makefile and CI workflows to include the `-n auto` option for pytest, enabling parallel test execution for the starter project template tests. This change enhances test performance and efficiency across the codebase.

* chore: Remove  news-aggregated.json file

Deleted the news-aggregated.json file

* Update test_template_validation.py

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
Gabriel Luiz Freitas Almeida 2025-07-29 19:32:48 -03:00 • committed by GitHub
commit cd4464d6b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 666 additions and 307 deletions

View file

@ -232,7 +232,7 @@ jobs:
- name: Test all starter project templates - name: Test all starter project templates
run: | run: |
uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v -n auto
# https://github.com/langchain-ai/langchain/blob/master/.github/workflows/check_diffs.yml # https://github.com/langchain-ai/langchain/blob/master/.github/workflows/check_diffs.yml
ci_success: ci_success:

View file

@ -37,4 +37,4 @@ jobs:
- name: Test all starter project templates - name: Test all starter project templates
run: | run: |
uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v -n auto

View file

@ -169,7 +169,7 @@ tests: ## run unit, integration, coverage tests
template_tests: ## run all starter project template tests template_tests: ## run all starter project template tests
@echo 'Running Starter Project Template Tests...' @echo 'Running Starter Project Template Tests...'
@uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v @uv run pytest src/backend/tests/unit/template/test_starter_projects.py -v -n auto
###################### ######################
# CODE QUALITY # CODE QUALITY

View file

@ -9,12 +9,16 @@
"dataType": "Prompt", "dataType": "Prompt",
"id": "Prompt-WvveL", "id": "Prompt-WvveL",
"name": "prompt", "name": "prompt",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "system_prompt", "fieldName": "system_prompt",
"id": "Agent-X1iAT", "id": "Agent-X1iAT",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -33,12 +37,16 @@
"dataType": "Prompt", "dataType": "Prompt",
"id": "Prompt-6JL4E", "id": "Prompt-6JL4E",
"name": "prompt", "name": "prompt",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "system_prompt", "fieldName": "system_prompt",
"id": "Agent-EQcU8", "id": "Agent-EQcU8",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -57,12 +65,17 @@
"dataType": "Agent", "dataType": "Agent",
"id": "Agent-EQcU8", "id": "Agent-EQcU8",
"name": "response", "name": "response",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "finance_agent_output", "fieldName": "finance_agent_output",
"id": "Prompt-WvveL", "id": "Prompt-WvveL",
"inputTypes": ["Message", "Text"], "inputTypes": [
"Message",
"Text"
],
"type": "str" "type": "str"
} }
}, },
@ -81,12 +94,16 @@
"dataType": "ChatInput", "dataType": "ChatInput",
"id": "ChatInput-NuUHZ", "id": "ChatInput-NuUHZ",
"name": "message", "name": "message",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_value", "fieldName": "input_value",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -105,12 +122,16 @@
"dataType": "Prompt", "dataType": "Prompt",
"id": "Prompt-ajhmq", "id": "Prompt-ajhmq",
"name": "prompt", "name": "prompt",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "system_prompt", "fieldName": "system_prompt",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -129,12 +150,16 @@
"dataType": "Agent", "dataType": "Agent",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"name": "response", "name": "response",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_value", "fieldName": "input_value",
"id": "Agent-EQcU8", "id": "Agent-EQcU8",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -153,12 +178,17 @@
"dataType": "Agent", "dataType": "Agent",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"name": "response", "name": "response",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "research_agent_output", "fieldName": "research_agent_output",
"id": "Prompt-WvveL", "id": "Prompt-WvveL",
"inputTypes": ["Message", "Text"], "inputTypes": [
"Message",
"Text"
],
"type": "str" "type": "str"
} }
}, },
@ -177,12 +207,16 @@
"dataType": "CalculatorComponent", "dataType": "CalculatorComponent",
"id": "CalculatorComponent-0P2yI", "id": "CalculatorComponent-0P2yI",
"name": "component_as_tool", "name": "component_as_tool",
"output_types": ["Tool"] "output_types": [
"Tool"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "tools", "fieldName": "tools",
"id": "Agent-X1iAT", "id": "Agent-X1iAT",
"inputTypes": ["Tool"], "inputTypes": [
"Tool"
],
"type": "other" "type": "other"
} }
}, },
@ -201,12 +235,16 @@
"dataType": "YfinanceComponent", "dataType": "YfinanceComponent",
"id": "YfinanceComponent-hAneS", "id": "YfinanceComponent-hAneS",
"name": "component_as_tool", "name": "component_as_tool",
"output_types": ["Tool"] "output_types": [
"Tool"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "tools", "fieldName": "tools",
"id": "Agent-EQcU8", "id": "Agent-EQcU8",
"inputTypes": ["Tool"], "inputTypes": [
"Tool"
],
"type": "other" "type": "other"
} }
}, },
@ -225,12 +263,16 @@
"dataType": "TavilySearchComponent", "dataType": "TavilySearchComponent",
"id": "TavilySearchComponent-DTUmi", "id": "TavilySearchComponent-DTUmi",
"name": "component_as_tool", "name": "component_as_tool",
"output_types": ["Tool"] "output_types": [
"Tool"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "tools", "fieldName": "tools",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"inputTypes": ["Tool"], "inputTypes": [
"Tool"
],
"type": "other" "type": "other"
} }
}, },
@ -249,12 +291,18 @@
"dataType": "Agent", "dataType": "Agent",
"id": "Agent-X1iAT", "id": "Agent-X1iAT",
"name": "response", "name": "response",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_value", "fieldName": "input_value",
"id": "ChatOutput-gbqPo", "id": "ChatOutput-gbqPo",
"inputTypes": ["Data", "DataFrame", "Message"], "inputTypes": [
"Data",
"DataFrame",
"Message"
],
"type": "other" "type": "other"
} }
}, },
@ -273,7 +321,9 @@
"display_name": "Finance Agent", "display_name": "Finance Agent",
"id": "Agent-EQcU8", "id": "Agent-EQcU8",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -322,7 +372,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -354,7 +406,9 @@
"display_name": "Agent Description [Deprecated]", "display_name": "Agent Description [Deprecated]",
"dynamic": false, "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.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -475,7 +529,9 @@
"display_name": "Input", "display_name": "Input",
"dynamic": false, "dynamic": false,
"info": "The input provided by the user for the agent to process.", "info": "The input provided by the user for the agent to process.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -683,7 +739,9 @@
"display_name": "Agent Instructions", "display_name": "Agent Instructions",
"dynamic": false, "dynamic": false,
"info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -751,7 +809,9 @@
"display_name": "Tools", "display_name": "Tools",
"dynamic": false, "dynamic": false,
"info": "These are the tools that the agent can use to help with tasks.", "info": "These are the tools that the agent can use to help with tasks.",
"input_types": ["Tool"], "input_types": [
"Tool"
],
"list": true, "list": true,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "tools", "name": "tools",
@ -812,7 +872,9 @@
"display_name": "Analysis & Editor Agent", "display_name": "Analysis & Editor Agent",
"id": "Agent-X1iAT", "id": "Agent-X1iAT",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -861,7 +923,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -893,7 +957,9 @@
"display_name": "Agent Description [Deprecated]", "display_name": "Agent Description [Deprecated]",
"dynamic": false, "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.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1014,7 +1080,9 @@
"display_name": "Input", "display_name": "Input",
"dynamic": false, "dynamic": false,
"info": "The input provided by the user for the agent to process.", "info": "The input provided by the user for the agent to process.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1222,7 +1290,9 @@
"display_name": "Agent Instructions", "display_name": "Agent Instructions",
"dynamic": false, "dynamic": false,
"info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1290,7 +1360,9 @@
"display_name": "Tools", "display_name": "Tools",
"dynamic": false, "dynamic": false,
"info": "These are the tools that the agent can use to help with tasks.", "info": "These are the tools that the agent can use to help with tasks.",
"input_types": ["Tool"], "input_types": [
"Tool"
],
"list": true, "list": true,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "tools", "name": "tools",
@ -1351,7 +1423,9 @@
"display_name": "Prompt", "display_name": "Prompt",
"id": "Prompt-ajhmq", "id": "Prompt-ajhmq",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": { "custom_fields": {
@ -1362,7 +1436,9 @@
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"error": null, "error": null,
"field_order": ["template"], "field_order": [
"template"
],
"frozen": false, "frozen": false,
"full_path": null, "full_path": null,
"icon": "braces", "icon": "braces",
@ -1387,7 +1463,9 @@
"name": "prompt", "name": "prompt",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1436,7 +1514,9 @@
"display_name": "Tool Placeholder", "display_name": "Tool Placeholder",
"dynamic": false, "dynamic": false,
"info": "A placeholder input for tool mode.", "info": "A placeholder input for tool mode.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "tool_placeholder", "name": "tool_placeholder",
@ -1481,7 +1561,9 @@
"display_name": "Prompt", "display_name": "Prompt",
"id": "Prompt-6JL4E", "id": "Prompt-6JL4E",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": { "custom_fields": {
@ -1492,7 +1574,9 @@
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"error": null, "error": null,
"field_order": ["template"], "field_order": [
"template"
],
"frozen": false, "frozen": false,
"full_path": null, "full_path": null,
"icon": "braces", "icon": "braces",
@ -1517,7 +1601,9 @@
"name": "prompt", "name": "prompt",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1566,7 +1652,9 @@
"display_name": "Tool Placeholder", "display_name": "Tool Placeholder",
"dynamic": false, "dynamic": false,
"info": "A placeholder input for tool mode.", "info": "A placeholder input for tool mode.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "tool_placeholder", "name": "tool_placeholder",
@ -1611,18 +1699,25 @@
"display_name": "Prompt", "display_name": "Prompt",
"id": "Prompt-WvveL", "id": "Prompt-WvveL",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": { "custom_fields": {
"template": ["research_agent_output", "finance_agent_output"] "template": [
"research_agent_output",
"finance_agent_output"
]
}, },
"description": "Create a prompt template with dynamic variables.", "description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt", "display_name": "Prompt",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"error": null, "error": null,
"field_order": ["template"], "field_order": [
"template"
],
"frozen": false, "frozen": false,
"full_path": null, "full_path": null,
"icon": "braces", "icon": "braces",
@ -1647,7 +1742,9 @@
"name": "prompt", "name": "prompt",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1680,7 +1777,10 @@
"fileTypes": [], "fileTypes": [],
"file_path": "", "file_path": "",
"info": "", "info": "",
"input_types": ["Message", "Text"], "input_types": [
"Message",
"Text"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"multiline": true, "multiline": true,
@ -1700,7 +1800,10 @@
"fileTypes": [], "fileTypes": [],
"file_path": "", "file_path": "",
"info": "", "info": "",
"input_types": ["Message", "Text"], "input_types": [
"Message",
"Text"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"multiline": true, "multiline": true,
@ -1736,7 +1839,9 @@
"display_name": "Tool Placeholder", "display_name": "Tool Placeholder",
"dynamic": false, "dynamic": false,
"info": "A placeholder input for tool mode.", "info": "A placeholder input for tool mode.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "tool_placeholder", "name": "tool_placeholder",
@ -1779,7 +1884,9 @@
"data": { "data": {
"id": "ChatInput-NuUHZ", "id": "ChatInput-NuUHZ",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -1817,7 +1924,9 @@
"name": "message", "name": "message",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1830,7 +1939,9 @@
"display_name": "Background Color", "display_name": "Background Color",
"dynamic": false, "dynamic": false,
"info": "The background color of the icon.", "info": "The background color of the icon.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "background_color", "name": "background_color",
@ -1850,7 +1961,9 @@
"display_name": "Icon", "display_name": "Icon",
"dynamic": false, "dynamic": false,
"info": "The icon of the message.", "info": "The icon of the message.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "chat_icon", "name": "chat_icon",
@ -1954,7 +2067,10 @@
"dynamic": false, "dynamic": false,
"info": "Type of sender.", "info": "Type of sender.",
"name": "sender", "name": "sender",
"options": ["Machine", "User"], "options": [
"Machine",
"User"
],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
"show": true, "show": true,
@ -1970,7 +2086,9 @@
"display_name": "Sender Name", "display_name": "Sender Name",
"dynamic": false, "dynamic": false,
"info": "Name of the sender.", "info": "Name of the sender.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "sender_name", "name": "sender_name",
@ -1990,7 +2108,9 @@
"display_name": "Session ID", "display_name": "Session ID",
"dynamic": false, "dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", "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, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "session_id", "name": "session_id",
@ -2026,7 +2146,9 @@
"display_name": "Text Color", "display_name": "Text Color",
"dynamic": false, "dynamic": false,
"info": "The text color of the name", "info": "The text color of the name",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"name": "text_color", "name": "text_color",
@ -2106,7 +2228,9 @@
"display_name": "Researcher Agent", "display_name": "Researcher Agent",
"id": "Agent-b7nmW", "id": "Agent-b7nmW",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -2155,7 +2279,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -2187,7 +2313,9 @@
"display_name": "Agent Description [Deprecated]", "display_name": "Agent Description [Deprecated]",
"dynamic": false, "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.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2308,7 +2436,9 @@
"display_name": "Input", "display_name": "Input",
"dynamic": false, "dynamic": false,
"info": "The input provided by the user for the agent to process.", "info": "The input provided by the user for the agent to process.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2516,7 +2646,9 @@
"display_name": "Agent Instructions", "display_name": "Agent Instructions",
"dynamic": false, "dynamic": false,
"info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2584,7 +2716,9 @@
"display_name": "Tools", "display_name": "Tools",
"dynamic": false, "dynamic": false,
"info": "These are the tools that the agent can use to help with tasks.", "info": "These are the tools that the agent can use to help with tasks.",
"input_types": ["Tool"], "input_types": [
"Tool"
],
"list": true, "list": true,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "tools", "name": "tools",
@ -2645,7 +2779,11 @@
"display_name": "Yahoo! Finance", "display_name": "Yahoo! Finance",
"id": "YfinanceComponent-hAneS", "id": "YfinanceComponent-hAneS",
"node": { "node": {
"base_classes": ["Data", "DataFrame", "Message"], "base_classes": [
"Data",
"DataFrame",
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -2653,7 +2791,11 @@
"display_name": "Yahoo! Finance", "display_name": "Yahoo! Finance",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"field_order": ["symbol", "method", "num_news"], "field_order": [
"symbol",
"method",
"num_news"
],
"frozen": false, "frozen": false,
"icon": "trending-up", "icon": "trending-up",
"legacy": false, "legacy": false,
@ -2676,7 +2818,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Tool", "selected": "Tool",
"tool_mode": true, "tool_mode": true,
"types": ["Tool"], "types": [
"Tool"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -2771,7 +2915,9 @@
"display_name": "Stock Symbol", "display_name": "Stock Symbol",
"dynamic": false, "dynamic": false,
"info": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).", "info": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2819,7 +2965,9 @@
"name": "fetch_content_dataframe", "name": "fetch_content_dataframe",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["fetch_content_dataframe"] "tags": [
"fetch_content_dataframe"
]
} }
] ]
} }
@ -2847,7 +2995,9 @@
"data": { "data": {
"id": "CalculatorComponent-0P2yI", "id": "CalculatorComponent-0P2yI",
"node": { "node": {
"base_classes": ["Data"], "base_classes": [
"Data"
],
"beta": false, "beta": false,
"category": "tools", "category": "tools",
"conditional_paths": [], "conditional_paths": [],
@ -2856,7 +3006,9 @@
"display_name": "Calculator", "display_name": "Calculator",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"field_order": ["expression"], "field_order": [
"expression"
],
"frozen": false, "frozen": false,
"icon": "calculator", "icon": "calculator",
"key": "CalculatorComponent", "key": "CalculatorComponent",
@ -2880,7 +3032,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Tool", "selected": "Tool",
"tool_mode": true, "tool_mode": true,
"types": ["Tool"], "types": [
"Tool"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -2912,7 +3066,9 @@
"display_name": "Expression", "display_name": "Expression",
"dynamic": false, "dynamic": false,
"info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2960,7 +3116,9 @@
"name": "evaluate_expression", "name": "evaluate_expression",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["evaluate_expression"] "tags": [
"evaluate_expression"
]
} }
] ]
} }
@ -2988,7 +3146,10 @@
"data": { "data": {
"id": "TavilySearchComponent-DTUmi", "id": "TavilySearchComponent-DTUmi",
"node": { "node": {
"base_classes": ["Data", "Message"], "base_classes": [
"Data",
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -3028,7 +3189,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Tool", "selected": "Tool",
"tool_mode": true, "tool_mode": true,
"types": ["Tool"], "types": [
"Tool"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -3112,7 +3275,9 @@
"display_name": "Exclude Domains", "display_name": "Exclude Domains",
"dynamic": false, "dynamic": false,
"info": "Comma-separated list of domains to exclude from the search results.", "info": "Comma-separated list of domains to exclude from the search results.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3151,7 +3316,9 @@
"display_name": "Include Domains", "display_name": "Include Domains",
"dynamic": false, "dynamic": false,
"info": "Comma-separated list of domains to include in the search results.", "info": "Comma-separated list of domains to include in the search results.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3226,7 +3393,9 @@
"display_name": "Search Query", "display_name": "Search Query",
"dynamic": false, "dynamic": false,
"info": "The search query you want to execute with Tavily.", "info": "The search query you want to execute with Tavily.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3250,7 +3419,10 @@
"dynamic": false, "dynamic": false,
"info": "The depth of the search.", "info": "The depth of the search.",
"name": "search_depth", "name": "search_depth",
"options": ["basic", "advanced"], "options": [
"basic",
"advanced"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -3270,7 +3442,12 @@
"dynamic": false, "dynamic": false,
"info": "The time range back from the current date to filter results.", "info": "The time range back from the current date to filter results.",
"name": "time_range", "name": "time_range",
"options": ["day", "week", "month", "year"], "options": [
"day",
"week",
"month",
"year"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -3313,7 +3490,9 @@
"name": "fetch_content_dataframe", "name": "fetch_content_dataframe",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["fetch_content_dataframe"] "tags": [
"fetch_content_dataframe"
]
} }
] ]
}, },
@ -3326,7 +3505,10 @@
"dynamic": false, "dynamic": false,
"info": "The category of the search.", "info": "The category of the search.",
"name": "topic", "name": "topic",
"options": ["general", "news"], "options": [
"general",
"news"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -3361,7 +3543,9 @@
"data": { "data": {
"id": "ChatOutput-gbqPo", "id": "ChatOutput-gbqPo",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"category": "outputs", "category": "outputs",
"conditional_paths": [], "conditional_paths": [],
@ -3402,7 +3586,9 @@
"name": "message", "name": "message",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -3416,7 +3602,9 @@
"display_name": "Background Color", "display_name": "Background Color",
"dynamic": false, "dynamic": false,
"info": "The background color of the icon.", "info": "The background color of the icon.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3437,7 +3625,9 @@
"display_name": "Icon", "display_name": "Icon",
"dynamic": false, "dynamic": false,
"info": "The icon of the message.", "info": "The icon of the message.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3494,7 +3684,9 @@
"display_name": "Data Template", "display_name": "Data Template",
"dynamic": false, "dynamic": false,
"info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3515,7 +3707,11 @@
"display_name": "Inputs", "display_name": "Inputs",
"dynamic": false, "dynamic": false,
"info": "Message to be passed as output.", "info": "Message to be passed as output.",
"input_types": ["Data", "DataFrame", "Message"], "input_types": [
"Data",
"DataFrame",
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "input_value", "name": "input_value",
@ -3536,7 +3732,10 @@
"dynamic": false, "dynamic": false,
"info": "Type of sender.", "info": "Type of sender.",
"name": "sender", "name": "sender",
"options": ["Machine", "User"], "options": [
"Machine",
"User"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -3553,7 +3752,9 @@
"display_name": "Sender Name", "display_name": "Sender Name",
"dynamic": false, "dynamic": false,
"info": "Name of the sender.", "info": "Name of the sender.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3574,7 +3775,9 @@
"display_name": "Session ID", "display_name": "Session ID",
"dynamic": false, "dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3613,7 +3816,9 @@
"display_name": "Text Color", "display_name": "Text Color",
"dynamic": false, "dynamic": false,
"info": "The text color of the name", "info": "The text color of the name",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -3660,5 +3865,9 @@
"is_component": false, "is_component": false,
"last_tested_version": "1.4.3", "last_tested_version": "1.4.3",
"name": "Sequential Tasks Agents", "name": "Sequential Tasks Agents",
"tags": ["assistants", "agents", "web-scraping"] "tags": [
"assistants",
"agents",
"web-scraping"
]
} }

View file

@ -9,12 +9,16 @@
"dataType": "YouTubeCommentsComponent", "dataType": "YouTubeCommentsComponent",
"id": "YouTubeCommentsComponent-y3wJZ", "id": "YouTubeCommentsComponent-y3wJZ",
"name": "comments", "name": "comments",
"output_types": ["DataFrame"] "output_types": [
"DataFrame"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "df", "fieldName": "df",
"id": "BatchRunComponent-30WdR", "id": "BatchRunComponent-30WdR",
"inputTypes": ["DataFrame"], "inputTypes": [
"DataFrame"
],
"type": "other" "type": "other"
} }
}, },
@ -33,12 +37,16 @@
"dataType": "Prompt", "dataType": "Prompt",
"id": "Prompt-yqoLt", "id": "Prompt-yqoLt",
"name": "prompt", "name": "prompt",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_value", "fieldName": "input_value",
"id": "Agent-JRSRu", "id": "Agent-JRSRu",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -57,12 +65,18 @@
"dataType": "Agent", "dataType": "Agent",
"id": "Agent-JRSRu", "id": "Agent-JRSRu",
"name": "response", "name": "response",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_value", "fieldName": "input_value",
"id": "ChatOutput-vlskP", "id": "ChatOutput-vlskP",
"inputTypes": ["Data", "DataFrame", "Message"], "inputTypes": [
"Data",
"DataFrame",
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -81,12 +95,16 @@
"dataType": "YouTubeTranscripts", "dataType": "YouTubeTranscripts",
"id": "YouTubeTranscripts-TlFcG", "id": "YouTubeTranscripts-TlFcG",
"name": "component_as_tool", "name": "component_as_tool",
"output_types": ["Tool"] "output_types": [
"Tool"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "tools", "fieldName": "tools",
"id": "Agent-JRSRu", "id": "Agent-JRSRu",
"inputTypes": ["Tool"], "inputTypes": [
"Tool"
],
"type": "other" "type": "other"
} }
}, },
@ -105,12 +123,17 @@
"dataType": "BatchRunComponent", "dataType": "BatchRunComponent",
"id": "BatchRunComponent-30WdR", "id": "BatchRunComponent-30WdR",
"name": "batch_results", "name": "batch_results",
"output_types": ["DataFrame"] "output_types": [
"DataFrame"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "input_data", "fieldName": "input_data",
"id": "parser-k0Bpy", "id": "parser-k0Bpy",
"inputTypes": ["DataFrame", "Data"], "inputTypes": [
"DataFrame",
"Data"
],
"type": "other" "type": "other"
} }
}, },
@ -129,12 +152,16 @@
"dataType": "parser", "dataType": "parser",
"id": "parser-k0Bpy", "id": "parser-k0Bpy",
"name": "parsed_text", "name": "parsed_text",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "analysis", "fieldName": "analysis",
"id": "Prompt-yqoLt", "id": "Prompt-yqoLt",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -153,12 +180,16 @@
"dataType": "LanguageModelComponent", "dataType": "LanguageModelComponent",
"id": "LanguageModelComponent-OvIt5", "id": "LanguageModelComponent-OvIt5",
"name": "model_output", "name": "model_output",
"output_types": ["LanguageModel"] "output_types": [
"LanguageModel"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "model", "fieldName": "model",
"id": "BatchRunComponent-30WdR", "id": "BatchRunComponent-30WdR",
"inputTypes": ["LanguageModel"], "inputTypes": [
"LanguageModel"
],
"type": "other" "type": "other"
} }
}, },
@ -177,12 +208,16 @@
"dataType": "ChatInput", "dataType": "ChatInput",
"id": "ChatInput-kaWcL", "id": "ChatInput-kaWcL",
"name": "message", "name": "message",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "video_url", "fieldName": "video_url",
"id": "YouTubeCommentsComponent-y3wJZ", "id": "YouTubeCommentsComponent-y3wJZ",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -201,12 +236,16 @@
"dataType": "ChatInput", "dataType": "ChatInput",
"id": "ChatInput-kaWcL", "id": "ChatInput-kaWcL",
"name": "message", "name": "message",
"output_types": ["Message"] "output_types": [
"Message"
]
}, },
"targetHandle": { "targetHandle": {
"fieldName": "url", "fieldName": "url",
"id": "Prompt-yqoLt", "id": "Prompt-yqoLt",
"inputTypes": ["Message"], "inputTypes": [
"Message"
],
"type": "str" "type": "str"
} }
}, },
@ -223,7 +262,9 @@
"data": { "data": {
"id": "BatchRunComponent-30WdR", "id": "BatchRunComponent-30WdR",
"node": { "node": {
"base_classes": ["DataFrame"], "base_classes": [
"DataFrame"
],
"beta": false, "beta": false,
"category": "helpers", "category": "helpers",
"conditional_paths": [], "conditional_paths": [],
@ -232,7 +273,12 @@
"display_name": "Batch Run", "display_name": "Batch Run",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"field_order": ["model", "system_message", "df", "column_name"], "field_order": [
"model",
"system_message",
"df",
"column_name"
],
"frozen": false, "frozen": false,
"icon": "List", "icon": "List",
"key": "BatchRunComponent", "key": "BatchRunComponent",
@ -254,7 +300,9 @@
"name": "batch_results", "name": "batch_results",
"selected": "DataFrame", "selected": "DataFrame",
"tool_mode": true, "tool_mode": true,
"types": ["DataFrame"], "types": [
"DataFrame"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -305,7 +353,9 @@
"display_name": "DataFrame", "display_name": "DataFrame",
"dynamic": false, "dynamic": false,
"info": "The DataFrame whose column (specified by 'column_name') we'll treat as text messages.", "info": "The DataFrame whose column (specified by 'column_name') we'll treat as text messages.",
"input_types": ["DataFrame"], "input_types": [
"DataFrame"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "df", "name": "df",
@ -343,7 +393,9 @@
"display_name": "Language Model", "display_name": "Language Model",
"dynamic": false, "dynamic": false,
"info": "Connect the 'Language Model' output from your LLM component here.", "info": "Connect the 'Language Model' output from your LLM component here.",
"input_types": ["LanguageModel"], "input_types": [
"LanguageModel"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "model", "name": "model",
@ -361,7 +413,9 @@
"display_name": "Output Column Name", "display_name": "Output Column Name",
"dynamic": false, "dynamic": false,
"info": "Name of the column where the model's response will be stored.", "info": "Name of the column where the model's response will be stored.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -382,7 +436,9 @@
"display_name": "Instructions", "display_name": "Instructions",
"dynamic": false, "dynamic": false,
"info": "Multi-line system instruction for all rows in the DataFrame.", "info": "Multi-line system instruction for all rows in the DataFrame.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -422,7 +478,9 @@
"data": { "data": {
"id": "YouTubeCommentsComponent-y3wJZ", "id": "YouTubeCommentsComponent-y3wJZ",
"node": { "node": {
"base_classes": ["DataFrame"], "base_classes": [
"DataFrame"
],
"beta": false, "beta": false,
"category": "youtube", "category": "youtube",
"conditional_paths": [], "conditional_paths": [],
@ -460,7 +518,9 @@
"name": "comments", "name": "comments",
"selected": "DataFrame", "selected": "DataFrame",
"tool_mode": true, "tool_mode": true,
"types": ["DataFrame"], "types": [
"DataFrame"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -566,7 +626,10 @@
"dynamic": false, "dynamic": false,
"info": "Sort comments by time or relevance.", "info": "Sort comments by time or relevance.",
"name": "sort_by", "name": "sort_by",
"options": ["time", "relevance"], "options": [
"time",
"relevance"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -583,7 +646,9 @@
"display_name": "Video URL", "display_name": "Video URL",
"dynamic": false, "dynamic": false,
"info": "The URL of the YouTube video to get comments from.", "info": "The URL of the YouTube video to get comments from.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -622,7 +687,9 @@
"data": { "data": {
"id": "Agent-JRSRu", "id": "Agent-JRSRu",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -673,7 +740,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -705,7 +774,9 @@
"display_name": "Agent Description [Deprecated]", "display_name": "Agent Description [Deprecated]",
"dynamic": false, "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.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -826,7 +897,9 @@
"display_name": "Input", "display_name": "Input",
"dynamic": false, "dynamic": false,
"info": "The input provided by the user for the agent to process.", "info": "The input provided by the user for the agent to process.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1034,7 +1107,9 @@
"display_name": "Agent Instructions", "display_name": "Agent Instructions",
"dynamic": false, "dynamic": false,
"info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1102,7 +1177,9 @@
"display_name": "Tools", "display_name": "Tools",
"dynamic": false, "dynamic": false,
"info": "These are the tools that the agent can use to help with tasks.", "info": "These are the tools that the agent can use to help with tasks.",
"input_types": ["Tool"], "input_types": [
"Tool"
],
"list": true, "list": true,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "tools", "name": "tools",
@ -1156,18 +1233,26 @@
"data": { "data": {
"id": "Prompt-yqoLt", "id": "Prompt-yqoLt",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": { "custom_fields": {
"template": ["url", "analysis"] "template": [
"url",
"analysis"
]
}, },
"description": "Create a prompt template with dynamic variables.", "description": "Create a prompt template with dynamic variables.",
"display_name": "Prompt", "display_name": "Prompt",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"error": null, "error": null,
"field_order": ["template", "tool_placeholder"], "field_order": [
"template",
"tool_placeholder"
],
"frozen": false, "frozen": false,
"full_path": null, "full_path": null,
"icon": "braces", "icon": "braces",
@ -1190,7 +1275,9 @@
"name": "prompt", "name": "prompt",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1205,7 +1292,9 @@
"fileTypes": [], "fileTypes": [],
"file_path": "", "file_path": "",
"info": "", "info": "",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"multiline": true, "multiline": true,
@ -1259,7 +1348,9 @@
"display_name": "Tool Placeholder", "display_name": "Tool Placeholder",
"dynamic": false, "dynamic": false,
"info": "A placeholder input for tool mode.", "info": "A placeholder input for tool mode.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1282,7 +1373,9 @@
"fileTypes": [], "fileTypes": [],
"file_path": "", "file_path": "",
"info": "", "info": "",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"load_from_db": false, "load_from_db": false,
"multiline": true, "multiline": true,
@ -1318,7 +1411,9 @@
"data": { "data": {
"id": "ChatOutput-vlskP", "id": "ChatOutput-vlskP",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"category": "outputs", "category": "outputs",
"conditional_paths": [], "conditional_paths": [],
@ -1359,7 +1454,9 @@
"name": "message", "name": "message",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1373,7 +1470,9 @@
"display_name": "Background Color", "display_name": "Background Color",
"dynamic": false, "dynamic": false,
"info": "The background color of the icon.", "info": "The background color of the icon.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1394,7 +1493,9 @@
"display_name": "Icon", "display_name": "Icon",
"dynamic": false, "dynamic": false,
"info": "The icon of the message.", "info": "The icon of the message.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1451,7 +1552,9 @@
"display_name": "Data Template", "display_name": "Data Template",
"dynamic": false, "dynamic": false,
"info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1472,7 +1575,11 @@
"display_name": "Inputs", "display_name": "Inputs",
"dynamic": false, "dynamic": false,
"info": "Message to be passed as output.", "info": "Message to be passed as output.",
"input_types": ["Data", "DataFrame", "Message"], "input_types": [
"Data",
"DataFrame",
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1496,7 +1603,10 @@
"dynamic": false, "dynamic": false,
"info": "Type of sender.", "info": "Type of sender.",
"name": "sender", "name": "sender",
"options": ["Machine", "User"], "options": [
"Machine",
"User"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -1513,7 +1623,9 @@
"display_name": "Sender Name", "display_name": "Sender Name",
"dynamic": false, "dynamic": false,
"info": "Name of the sender.", "info": "Name of the sender.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1534,7 +1646,9 @@
"display_name": "Session ID", "display_name": "Session ID",
"dynamic": false, "dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1573,7 +1687,9 @@
"display_name": "Text Color", "display_name": "Text Color",
"dynamic": false, "dynamic": false,
"info": "The text color of the name", "info": "The text color of the name",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1611,7 +1727,11 @@
"data": { "data": {
"id": "YouTubeTranscripts-TlFcG", "id": "YouTubeTranscripts-TlFcG",
"node": { "node": {
"base_classes": ["Data", "DataFrame", "Message"], "base_classes": [
"Data",
"DataFrame",
"Message"
],
"beta": false, "beta": false,
"conditional_paths": [], "conditional_paths": [],
"custom_fields": {}, "custom_fields": {},
@ -1619,7 +1739,11 @@
"display_name": "YouTube Transcripts", "display_name": "YouTube Transcripts",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"field_order": ["url", "chunk_size_seconds", "translation"], "field_order": [
"url",
"chunk_size_seconds",
"translation"
],
"frozen": false, "frozen": false,
"icon": "YouTube", "icon": "YouTube",
"last_updated": "2025-07-07T14:52:15.000Z", "last_updated": "2025-07-07T14:52:15.000Z",
@ -1644,7 +1768,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Tool", "selected": "Tool",
"tool_mode": true, "tool_mode": true,
"types": ["Tool"], "types": [
"Tool"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1719,7 +1845,9 @@
"name": "get_dataframe_output", "name": "get_dataframe_output",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["get_dataframe_output"] "tags": [
"get_dataframe_output"
]
}, },
{ {
"args": { "args": {
@ -1735,7 +1863,9 @@
"name": "get_message_output", "name": "get_message_output",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["get_message_output"] "tags": [
"get_message_output"
]
}, },
{ {
"args": { "args": {
@ -1751,7 +1881,9 @@
"name": "get_data_output", "name": "get_data_output",
"readonly": false, "readonly": false,
"status": true, "status": true,
"tags": ["get_data_output"] "tags": [
"get_data_output"
]
} }
] ]
}, },
@ -1795,7 +1927,9 @@
"display_name": "Video URL", "display_name": "Video URL",
"dynamic": false, "dynamic": false,
"info": "Enter the YouTube video URL to get transcripts from.", "info": "Enter the YouTube video URL to get transcripts from.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1864,7 +1998,9 @@
"data": { "data": {
"id": "parser-k0Bpy", "id": "parser-k0Bpy",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"category": "processing", "category": "processing",
"conditional_paths": [], "conditional_paths": [],
@ -1873,7 +2009,12 @@
"display_name": "Parser", "display_name": "Parser",
"documentation": "", "documentation": "",
"edited": false, "edited": false,
"field_order": ["mode", "pattern", "input_data", "sep"], "field_order": [
"mode",
"pattern",
"input_data",
"sep"
],
"frozen": false, "frozen": false,
"icon": "braces", "icon": "braces",
"key": "parser", "key": "parser",
@ -1891,7 +2032,9 @@
"name": "parsed_text", "name": "parsed_text",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -1923,7 +2066,10 @@
"display_name": "Data or DataFrame", "display_name": "Data or DataFrame",
"dynamic": false, "dynamic": false,
"info": "Accepts either a DataFrame or a Data object.", "info": "Accepts either a DataFrame or a Data object.",
"input_types": ["DataFrame", "Data"], "input_types": [
"DataFrame",
"Data"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"name": "input_data", "name": "input_data",
@ -1942,7 +2088,10 @@
"dynamic": false, "dynamic": false,
"info": "Convert into raw string instead of using a template.", "info": "Convert into raw string instead of using a template.",
"name": "mode", "name": "mode",
"options": ["Parser", "Stringify"], "options": [
"Parser",
"Stringify"
],
"placeholder": "", "placeholder": "",
"real_time_refresh": true, "real_time_refresh": true,
"required": false, "required": false,
@ -1960,7 +2109,9 @@
"display_name": "Template", "display_name": "Template",
"dynamic": true, "dynamic": true,
"info": "Use variables within curly brackets to extract column values for DataFrames or key values for Data.For example: `Name: {Name}, Age: {Age}, Country: {Country}`", "info": "Use variables within curly brackets to extract column values for DataFrames or key values for Data.For example: `Name: {Name}, Age: {Age}, Country: {Country}`",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -1982,7 +2133,9 @@
"display_name": "Separator", "display_name": "Separator",
"dynamic": false, "dynamic": false,
"info": "String used to separate rows/items.", "info": "String used to separate rows/items.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2021,7 +2174,10 @@
"data": { "data": {
"id": "LanguageModelComponent-OvIt5", "id": "LanguageModelComponent-OvIt5",
"node": { "node": {
"base_classes": ["LanguageModel", "Message"], "base_classes": [
"LanguageModel",
"Message"
],
"beta": false, "beta": false,
"category": "models", "category": "models",
"conditional_paths": [], "conditional_paths": [],
@ -2067,7 +2223,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
}, },
{ {
@ -2081,7 +2239,9 @@
"required_inputs": null, "required_inputs": null,
"selected": "LanguageModel", "selected": "LanguageModel",
"tool_mode": true, "tool_mode": true,
"types": ["LanguageModel"], "types": [
"LanguageModel"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -2132,7 +2292,9 @@
"display_name": "Input", "display_name": "Input",
"dynamic": false, "dynamic": false,
"info": "The input text to send to the model", "info": "The input text to send to the model",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2188,7 +2350,11 @@
"dynamic": false, "dynamic": false,
"info": "Select the model provider", "info": "Select the model provider",
"name": "provider", "name": "provider",
"options": ["OpenAI", "Anthropic", "Google"], "options": [
"OpenAI",
"Anthropic",
"Google"
],
"options_metadata": [ "options_metadata": [
{ {
"icon": "OpenAI" "icon": "OpenAI"
@ -2236,7 +2402,9 @@
"display_name": "System Message", "display_name": "System Message",
"dynamic": false, "dynamic": false,
"info": "A system message that helps set the behavior of the assistant", "info": "A system message that helps set the behavior of the assistant",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2304,7 +2472,9 @@
"data": { "data": {
"id": "ChatInput-kaWcL", "id": "ChatInput-kaWcL",
"node": { "node": {
"base_classes": ["Message"], "base_classes": [
"Message"
],
"beta": false, "beta": false,
"category": "input_output", "category": "input_output",
"conditional_paths": [], "conditional_paths": [],
@ -2345,7 +2515,9 @@
"name": "message", "name": "message",
"selected": "Message", "selected": "Message",
"tool_mode": true, "tool_mode": true,
"types": ["Message"], "types": [
"Message"
],
"value": "__UNDEFINED__" "value": "__UNDEFINED__"
} }
], ],
@ -2359,7 +2531,9 @@
"display_name": "Background Color", "display_name": "Background Color",
"dynamic": false, "dynamic": false,
"info": "The background color of the icon.", "info": "The background color of the icon.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2380,7 +2554,9 @@
"display_name": "Icon", "display_name": "Icon",
"dynamic": false, "dynamic": false,
"info": "The icon of the message.", "info": "The icon of the message.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2489,7 +2665,10 @@
"dynamic": false, "dynamic": false,
"info": "Type of sender.", "info": "Type of sender.",
"name": "sender", "name": "sender",
"options": ["Machine", "User"], "options": [
"Machine",
"User"
],
"options_metadata": [], "options_metadata": [],
"placeholder": "", "placeholder": "",
"required": false, "required": false,
@ -2507,7 +2686,9 @@
"display_name": "Sender Name", "display_name": "Sender Name",
"dynamic": false, "dynamic": false,
"info": "Name of the sender.", "info": "Name of the sender.",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2528,7 +2709,9 @@
"display_name": "Session ID", "display_name": "Session ID",
"dynamic": false, "dynamic": false,
"info": "The session ID of the chat. If empty, the current session ID parameter will be used.", "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, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2567,7 +2750,9 @@
"display_name": "Text Color", "display_name": "Text Color",
"dynamic": false, "dynamic": false,
"info": "The text color of the name", "info": "The text color of the name",
"input_types": ["Message"], "input_types": [
"Message"
],
"list": false, "list": false,
"list_add_label": "Add More", "list_add_label": "Add More",
"load_from_db": false, "load_from_db": false,
@ -2614,5 +2799,8 @@
"is_component": false, "is_component": false,
"last_tested_version": "1.4.3", "last_tested_version": "1.4.3",
"name": "YouTube Analysis", "name": "YouTube Analysis",
"tags": ["agents", "assistants"] "tags": [
"agents",
"assistants"
]
} }

View file

@ -155,9 +155,7 @@ async def validate_flow_execution(
try: try:
# Create a flow from the template with timeout # Create a flow from the template with timeout
create_response = await asyncio.wait_for( create_response = await client.post("api/v1/flows/", json=template_data, headers=headers, timeout=10)
client.post("api/v1/flows/", json=template_data, headers=headers), timeout=10.0
)
if create_response.status_code != 201: # noqa: PLR2004 if create_response.status_code != 201: # noqa: PLR2004
errors.append(f"{filename}: Failed to create flow: {create_response.status_code}") errors.append(f"{filename}: Failed to create flow: {create_response.status_code}")
@ -167,9 +165,7 @@ async def validate_flow_execution(
try: try:
# Build the flow with timeout # Build the flow with timeout
build_response = await asyncio.wait_for( build_response = await client.post(f"api/v1/build/{flow_id}/flow", json={}, headers=headers, timeout=10)
client.post(f"api/v1/build/{flow_id}/flow", json={}, headers=headers), timeout=15.0
)
if build_response.status_code != 200: # noqa: PLR2004 if build_response.status_code != 200: # noqa: PLR2004
errors.append(f"{filename}: Failed to build flow: {build_response.status_code}") errors.append(f"{filename}: Failed to build flow: {build_response.status_code}")
@ -179,9 +175,7 @@ async def validate_flow_execution(
# Get build events to validate execution # Get build events to validate execution
events_headers = {**headers, "Accept": "application/x-ndjson"} events_headers = {**headers, "Accept": "application/x-ndjson"}
events_response = await asyncio.wait_for( events_response = await client.get(f"api/v1/build/{job_id}/events", headers=events_headers, timeout=10)
client.get(f"api/v1/build/{job_id}/events", headers=events_headers), timeout=10.0
)
if events_response.status_code != 200: # noqa: PLR2004 if events_response.status_code != 200: # noqa: PLR2004
errors.append(f"{filename}: Failed to get build events: {events_response.status_code}") errors.append(f"{filename}: Failed to get build events: {events_response.status_code}")
@ -193,7 +187,7 @@ async def validate_flow_execution(
finally: finally:
# Clean up the flow with timeout # Clean up the flow with timeout
try: # noqa: SIM105 try: # noqa: SIM105
await asyncio.wait_for(client.delete(f"api/v1/flows/{flow_id}", headers=headers), timeout=5.0) await client.delete(f"api/v1/flows/{flow_id}", headers=headers, timeout=10)
except asyncio.TimeoutError: except asyncio.TimeoutError:
# Log but don't fail if cleanup times out # Log but don't fail if cleanup times out
pass pass

View file

@ -168,11 +168,11 @@ async def _delete_transactions_and_vertex_builds(session, flows: list[Flow]):
continue continue
try: try:
await delete_vertex_builds_by_flow_id(session, flow_id) await delete_vertex_builds_by_flow_id(session, flow_id)
except Exception as e: # noqa: BLE001 except Exception as e:
logger.debug(f"Error deleting vertex builds for flow {flow_id}: {e}") logger.debug(f"Error deleting vertex builds for flow {flow_id}: {e}")
try: try:
await delete_transactions_by_flow_id(session, flow_id) await delete_transactions_by_flow_id(session, flow_id)
except Exception as e: # noqa: BLE001 except Exception as e:
logger.debug(f"Error deleting transactions for flow {flow_id}: {e}") logger.debug(f"Error deleting transactions for flow {flow_id}: {e}")
@ -474,7 +474,7 @@ async def active_user(client): # noqa: ARG001
user = await session.get(User, user.id, options=[selectinload(User.flows)]) user = await session.get(User, user.id, options=[selectinload(User.flows)])
await _delete_transactions_and_vertex_builds(session, user.flows) await _delete_transactions_and_vertex_builds(session, user.flows)
await session.commit() await session.commit()
except Exception as e: # noqa: BLE001 except Exception as e:
logger.exception(f"Error deleting transactions and vertex builds for user: {e}") logger.exception(f"Error deleting transactions and vertex builds for user: {e}")
try: try:
@ -482,7 +482,7 @@ async def active_user(client): # noqa: ARG001
user = await session.get(User, user.id) user = await session.get(User, user.id)
await session.delete(user) await session.delete(user)
await session.commit() await session.commit()
except Exception as e: # noqa: BLE001 except Exception as e:
logger.exception(f"Error deleting user: {e}") logger.exception(f"Error deleting user: {e}")

View file

@ -39,7 +39,7 @@ def astradb_client():
for collection in ALL_COLLECTIONS: for collection in ALL_COLLECTIONS:
try: # noqa: SIM105 try: # noqa: SIM105
client.drop_collection(collection) client.drop_collection(collection)
except Exception: # noqa: BLE001, S110 except Exception: # noqa: S110
pass pass

View file

@ -119,7 +119,7 @@ class FlowRunUser(FastHttpUser):
error_msg = f"Unexpected status code: {response.status_code}, Response: {error_text[:200]}" error_msg = f"Unexpected status code: {response.status_code}, Response: {error_text[:200]}"
response.failure(error_msg) response.failure(error_msg)
self.log_error(endpoint, Exception(error_msg), response_time) self.log_error(endpoint, Exception(error_msg), response_time)
except Exception as e: # noqa: BLE001 except Exception as e:
response_time = (time.time() - start_time) * 1000 response_time = (time.time() - start_time) * 1000
self.log_error(endpoint, e, response_time) self.log_error(endpoint, e, response_time)
response.failure(f"Error: {e}") response.failure(f"Error: {e}")

View file

@ -330,7 +330,7 @@ class TestAgentComponentWithClient(ComponentTestBaseWithClient):
if "4" not in response_text: if "4" not in response_text:
failed_models[model_name] = f"Expected '4' in response but got: {response_text}" failed_models[model_name] = f"Expected '4' in response but got: {response_text}"
except Exception as e: # noqa: BLE001 except Exception as e:
failed_models[model_name] = f"Exception occurred: {e!s}" failed_models[model_name] = f"Exception occurred: {e!s}"
assert not failed_models, "The following models failed the test:\n" + "\n".join( assert not failed_models, "The following models failed the test:\n" + "\n".join(

View file

@ -9,7 +9,6 @@ Tests all JSON templates in the starter_projects folder to ensure they:
Validates that templates work correctly and prevent unexpected breakage. Validates that templates work correctly and prevent unexpected breakage.
""" """
import asyncio
import json import json
from pathlib import Path from pathlib import Path
@ -28,6 +27,24 @@ def get_starter_projects_path() -> Path:
return Path("src/backend/base/langflow/initial_setup/starter_projects") return Path("src/backend/base/langflow/initial_setup/starter_projects")
def get_template_files():
"""Get all template files for parameterization."""
return list(get_starter_projects_path().glob("*.json"))
def get_basic_template_files():
"""Get basic template files for parameterization."""
path = get_starter_projects_path()
basic_templates = ["Basic Prompting.json", "Basic Prompt Chaining.json"]
return [path / name for name in basic_templates if (path / name).exists()]
@pytest.fixture(autouse=True)
def disable_tracing(monkeypatch):
"""Disable tracing for all template tests."""
monkeypatch.setenv("LANGFLOW_DEACTIVATE_TRACING", "true")
class TestStarterProjects: class TestStarterProjects:
"""Test all starter project templates.""" """Test all starter project templates."""
@ -36,129 +53,80 @@ class TestStarterProjects:
path = get_starter_projects_path() path = get_starter_projects_path()
assert path.exists(), f"Directory not found: {path}" assert path.exists(), f"Directory not found: {path}"
templates = list(path.glob("*.json")) templates = get_template_files()
assert len(templates) > 0, "No template files found" assert len(templates) > 0, "No template files found"
def test_all_templates_valid_json(self): @pytest.mark.parametrize("template_file", get_template_files(), ids=lambda x: x.name)
"""Test all templates are valid JSON.""" def test_template_valid_json(self, template_file):
path = get_starter_projects_path() """Test template is valid JSON."""
templates = list(path.glob("*.json"))
for template_file in templates:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
try: try:
json.load(f) json.load(f)
except json.JSONDecodeError as e: except json.JSONDecodeError as e:
pytest.fail(f"Invalid JSON in {template_file.name}: {e}") pytest.fail(f"Invalid JSON in {template_file.name}: {e}")
def test_all_templates_structure(self): @pytest.mark.parametrize("template_file", get_template_files(), ids=lambda x: x.name)
"""Test all templates have required structure.""" def test_template_structure(self, template_file):
path = get_starter_projects_path() """Test template has required structure."""
templates = list(path.glob("*.json"))
all_errors = []
for template_file in templates:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
template_data = json.load(f) template_data = json.load(f)
errors = validate_template_structure(template_data, template_file.name) errors = validate_template_structure(template_data, template_file.name)
all_errors.extend(errors) if errors:
error_msg = "\n".join(errors)
pytest.fail(f"Template structure errors in {template_file.name}:\n{error_msg}")
if all_errors: @pytest.mark.parametrize("template_file", get_template_files(), ids=lambda x: x.name)
error_msg = "\n".join(all_errors) def test_template_can_build_flow(self, template_file):
pytest.fail(f"Template structure errors:\n{error_msg}") """Test template can be built into working flow."""
def test_all_templates_can_build_flow(self):
"""Test all templates can be built into working flows."""
path = get_starter_projects_path()
templates = list(path.glob("*.json"))
all_errors = []
for template_file in templates:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
template_data = json.load(f) template_data = json.load(f)
errors = validate_flow_can_build(template_data, template_file.name) errors = validate_flow_can_build(template_data, template_file.name)
all_errors.extend(errors) if errors:
error_msg = "\n".join(errors)
if all_errors: pytest.fail(f"Flow build errors in {template_file.name}:\n{error_msg}")
error_msg = "\n".join(all_errors)
pytest.fail(f"Flow build errors:\n{error_msg}")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_all_templates_validate_endpoint(self, client, logged_in_headers): @pytest.mark.parametrize("template_file", get_template_files(), ids=lambda x: x.name)
"""Test all templates using the validate endpoint.""" async def test_template_validate_endpoint(self, template_file, client, logged_in_headers):
path = get_starter_projects_path() """Test template using the validate endpoint."""
templates = list(path.glob("*.json"))
all_errors = []
for template_file in templates:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
template_data = json.load(f) template_data = json.load(f)
errors = await validate_flow_execution(client, template_data, template_file.name, logged_in_headers) errors = await validate_flow_execution(client, template_data, template_file.name, logged_in_headers)
all_errors.extend(errors) if errors:
error_msg = "\n".join(errors)
if all_errors: pytest.fail(f"Endpoint validation errors in {template_file.name}:\n{error_msg}")
error_msg = "\n".join(all_errors)
pytest.fail(f"Endpoint validation errors:\n{error_msg}")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_all_templates_flow_execution(self, client, logged_in_headers): @pytest.mark.parametrize("template_file", get_template_files(), ids=lambda x: x.name)
"""Test all templates can execute successfully.""" async def test_template_flow_execution(self, template_file, client, logged_in_headers):
path = get_starter_projects_path() """Test template can execute successfully."""
templates = list(path.glob("*.json"))
all_errors = []
# Process templates in chunks to avoid timeout issues
chunk_size = 5
template_chunks = [templates[i : i + chunk_size] for i in range(0, len(templates), chunk_size)]
for chunk in template_chunks:
for template_file in chunk:
try: try:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
template_data = json.load(f) template_data = json.load(f)
errors = await validate_flow_execution(client, template_data, template_file.name, logged_in_headers) errors = await validate_flow_execution(client, template_data, template_file.name, logged_in_headers)
all_errors.extend(errors) if errors:
error_msg = "\n".join(errors)
pytest.fail(f"Template execution errors in {template_file.name}:\n{error_msg}")
except (ValueError, TypeError, KeyError, AttributeError, OSError, json.JSONDecodeError) as e: except (ValueError, TypeError, KeyError, AttributeError, OSError, json.JSONDecodeError) as e:
error_msg = f"{template_file.name}: Unexpected error during validation: {e!s}" pytest.fail(f"{template_file.name}: Unexpected error during validation: {e!s}")
all_errors.append(error_msg)
# Brief pause between chunks to avoid overwhelming the system
await asyncio.sleep(0.5)
# All templates must pass - no failures allowed
if all_errors:
error_msg = "\n".join(all_errors)
pytest.fail(f"Template execution errors:\n{error_msg}")
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_basic_templates_flow_execution(self, client, logged_in_headers): @pytest.mark.parametrize("template_file", get_basic_template_files(), ids=lambda x: x.name)
"""Test basic templates can execute successfully.""" async def test_basic_template_flow_execution(self, template_file, client, logged_in_headers):
path = get_starter_projects_path() """Test basic template can execute successfully."""
# Only test basic templates that should reliably work
basic_templates = ["Basic Prompting.json", "Basic Prompt Chaining.json"]
all_errors = []
for template_name in basic_templates:
template_file = path / template_name
if template_file.exists():
try: try:
with template_file.open(encoding="utf-8") as f: with template_file.open(encoding="utf-8") as f:
template_data = json.load(f) template_data = json.load(f)
errors = await validate_flow_execution(client, template_data, template_name, logged_in_headers) errors = await validate_flow_execution(client, template_data, template_file.name, logged_in_headers)
all_errors.extend(errors) if errors:
error_msg = "\n".join(errors)
pytest.fail(f"Basic template execution errors in {template_file.name}:\n{error_msg}")
except (ValueError, TypeError, KeyError, AttributeError, OSError, json.JSONDecodeError) as e: except (ValueError, TypeError, KeyError, AttributeError, OSError, json.JSONDecodeError) as e:
all_errors.append(f"{template_name}: Unexpected error during validation: {e!s}") pytest.fail(f"{template_file.name}: Unexpected error during validation: {e!s}")
# All basic templates must pass - no failures allowed
if all_errors:
error_msg = "\n".join(all_errors)
pytest.fail(f"Basic template execution errors:\n{error_msg}")

View file

@ -464,14 +464,14 @@ class TestValidateFlowExecution:
mock_client.delete.return_value = Mock() mock_client.delete.return_value = Mock()
template_data = {"nodes": [], "edges": []} template_data = {"nodes": [], "edges": []}
headers = {"Authorization": "Bearer token"} headers = {"Authorization": "Bearer token", "timeout": 10}
errors = await validate_flow_execution(mock_client, template_data, "test.json", headers) errors = await validate_flow_execution(mock_client, template_data, "test.json", headers)
assert len(errors) == 1 assert len(errors) == 1
assert "Flow execution validation failed: Build error" in errors[0] assert "Flow execution validation failed: Build error" in errors[0]
# Verify cleanup was called # Verify cleanup was called
mock_client.delete.assert_called_once_with("api/v1/flows/flow123", headers=headers) mock_client.delete.assert_called_once_with("api/v1/flows/flow123", headers=headers, timeout=10)
class TestValidateEventStream: class TestValidateEventStream: