From f34ba4cd95dfb1576787ceff6c6fecf744557a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Johnny?= Date: Mon, 20 Jan 2025 22:28:13 -0300 Subject: [PATCH] fix: preserve template values in custom component updates (#5821) * fix: preserve template values in custom component updates * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- src/backend/base/langflow/api/v1/endpoints.py | 8 + .../Instagram Copywriter.json | 1275 +++++----- .../starter_projects/Research Agent.json | 1302 ++++++----- .../starter_projects/SaaS Pricing.json | 447 ++-- .../Sequential Tasks Agents .json | 2058 ++++++++++------- .../starter_projects/Simple Agent.json | 730 +++--- .../Travel Planning Agents.json | 1258 +++++----- 7 files changed, 4094 insertions(+), 2984 deletions(-) diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py index 4a04d8223..46a746008 100644 --- a/src/backend/base/langflow/api/v1/endpoints.py +++ b/src/backend/base/langflow/api/v1/endpoints.py @@ -720,6 +720,7 @@ async def custom_component_update( user_id=user.id, ) + template_data = code_request.model_dump().get("template", {}).copy() component_node["tool_mode"] = code_request.tool_mode if hasattr(cc_instance, "set_attributes"): @@ -747,6 +748,13 @@ async def custom_component_update( field_name=code_request.field, ) component_node["template"] = updated_build_config + + # Preserve previous field values by merging filtered template data into + # the component node's template. Only include entries where the value + # is a dictionary containing the key "value". + filtered_data = {k: v for k, v in template_data.items() if isinstance(v, dict) and "value" in v} + component_node["template"] |= filtered_data + if isinstance(cc_instance, Component): await cc_instance.run_and_validate_update_outputs( frontend_node=component_node, 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 3e066cd80..0fc520363 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 @@ -1,11 +1,288 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "TextInput", + "id": "TextInput-0rzBn", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "guidelines", + "id": "Prompt-j3woL", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-TextInput-0rzBn{œdataTypeœ:œTextInputœ,œidœ:œTextInput-0rzBnœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-j3woL{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "TextInput-0rzBn", + "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-0rzBnœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-j3woL", + "targetHandle": "{œfieldNameœ: œguidelinesœ, œidœ: œPrompt-j3woLœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-jxXfH", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "post", + "id": "Prompt-lqX5p", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-jxXfH{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-lqX5p{œfieldNameœ:œpostœ,œidœ:œPrompt-lqX5pœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-jxXfH", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-jxXfHœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-lqX5p", + "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-lqX5pœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-j3woL", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-jxXfH", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-j3woL{œdataTypeœ:œPromptœ,œidœ:œPrompt-j3woLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-jxXfH{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-jxXfHœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-j3woL", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-j3woLœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-jxXfH", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-jxXfHœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-pvWq5", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-TG1G2", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-pvWq5{œdataTypeœ:œChatInputœ,œidœ:œChatInput-pvWq5œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-TG1G2{œfieldNameœ:œinput_valueœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-pvWq5", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-pvWq5œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-TG1G2", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-TG1G2œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-TG1G2", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "context", + "id": "Prompt-j3woL", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-TG1G2{œdataTypeœ:œAgentœ,œidœ:œAgent-TG1G2œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-j3woL{œfieldNameœ:œcontextœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "Agent-TG1G2", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-TG1G2œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-j3woL", + "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-j3woLœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-lqX5p", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-Sef2w", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-lqX5p{œdataTypeœ:œPromptœ,œidœ:œPrompt-lqX5pœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-Sef2w{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Sef2wœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-lqX5p", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-lqX5pœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-Sef2w", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-Sef2wœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-jxXfH", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "post", + "id": "Prompt-R2EK8", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-jxXfH{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-R2EK8{œfieldNameœ:œpostœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-jxXfH", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-jxXfHœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-R2EK8", + "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-R2EK8œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": true, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-Sef2w", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "image_description", + "id": "Prompt-R2EK8", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-Sef2w{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Sef2wœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-R2EK8{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-Sef2w", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-Sef2wœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-R2EK8", + "targetHandle": "{œfieldNameœ: œimage_descriptionœ, œidœ: œPrompt-R2EK8œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-R2EK8", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-CnabR", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-R2EK8{œdataTypeœ:œPromptœ,œidœ:œPrompt-R2EK8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-CnabR{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-CnabRœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-R2EK8", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-R2EK8œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-CnabR", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-CnabRœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "TavilySearchComponent", + "id": "TavilySearchComponent-xQwoJ", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-TG1G2", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__TavilySearchComponent-xQwoJ{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-xQwoJœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-TG1G2{œfieldNameœ:œtoolsœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "TavilySearchComponent-xQwoJ", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-xQwoJœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-TG1G2", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-TG1G2œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { "id": "ChatInput-pvWq5", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -32,13 +309,15 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "message", + "cache": true, "display_name": "Message", "method": "message_response", - "value": "__UNDEFINED__", - "cache": true + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -50,7 +329,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -69,7 +350,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -83,22 +366,22 @@ "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import (\n DropdownInput,\n FileInput,\n MessageTextInput,\n MultilineInput,\n Output,\n)\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_USER,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatInput\"\n minimized = True\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n input_types=[],\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_USER,\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_USER,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n async def message_response(self) -> Message:\n background_color = self.background_color\n text_color = self.text_color\n icon = self.chat_icon\n\n message = await Message.create(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n properties={\n \"background_color\": background_color,\n \"text_color\": text_color,\n \"icon\": icon,\n },\n )\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import (\n DropdownInput,\n FileInput,\n MessageTextInput,\n MultilineInput,\n Output,\n)\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_USER,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatInput\"\n minimized = True\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n input_types=[],\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_USER,\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_USER,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n async def message_response(self) -> Message:\n background_color = self.background_color\n text_color = self.text_color\n icon = self.chat_icon\n\n message = await Message.create(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n properties={\n \"background_color\": background_color,\n \"text_color\": text_color,\n \"icon\": icon,\n },\n )\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n" }, "files": { "_input_type": "FileInput", @@ -170,7 +453,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -185,7 +471,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -204,7 +492,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -239,7 +529,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -281,17 +573,24 @@ "display_name": "Prompt", "id": "Prompt-j3woL", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["context", "guidelines"] + "template": [ + "context", + "guidelines" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -300,35 +599,37 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "prompt", + "cache": true, "display_name": "Prompt Message", "method": "build_prompt", - "value": "__UNDEFINED__", - "cache": true + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n" }, "context": { "advanced": false, @@ -338,7 +639,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -358,7 +662,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -394,7 +701,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -436,7 +745,9 @@ "data": { "id": "TextInput-0rzBn", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -444,7 +755,9 @@ "display_name": "Text Input", "documentation": "", "edited": false, - "field_order": ["input_value"], + "field_order": [ + "input_value" + ], "frozen": false, "icon": "type", "legacy": false, @@ -453,35 +766,37 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "text", + "cache": true, "display_name": "Message", "method": "text_response", - "value": "__UNDEFINED__", - "cache": true + "name": "text", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.io.text import TextComponent\nfrom langflow.io import MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n name = \"TextInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n return Message(\n text=self.input_value,\n )\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.text import TextComponent\nfrom langflow.io import MultilineInput, Output\nfrom langflow.schema.message import Message\n\n\nclass TextInputComponent(TextComponent):\n display_name = \"Text Input\"\n description = \"Get text inputs from the Playground.\"\n icon = \"type\"\n name = \"TextInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Text to be passed as input.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"text\", method=\"text_response\"),\n ]\n\n def text_response(self) -> Message:\n return Message(\n text=self.input_value,\n )\n" }, "input_value": { "_input_type": "MultilineInput", @@ -489,7 +804,9 @@ "display_name": "Text", "dynamic": false, "info": "Text to be passed as input.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -532,7 +849,10 @@ "display_name": "OpenAI", "id": "OpenAIModel-jxXfH", "node": { - "base_classes": ["LanguageModel", "Message"], + "base_classes": [ + "LanguageModel", + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -563,24 +883,28 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "text_output", + "cache": true, "display_name": "Message", "method": "text_response", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] + "name": "text_output", + "required_inputs": [], + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" }, { - "types": ["LanguageModel"], - "selected": "LanguageModel", - "name": "model_output", + "cache": true, "display_name": "Language Model", "method": "build_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] + "name": "model_output", + "required_inputs": [], + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -592,7 +916,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -604,22 +930,22 @@ "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n SliderInput(\n name=\"temperature\", display_name=\"Temperature\", value=0.1, range_spec=RangeSpec(min=0, max=2, step=0.01)\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n openai_api_key = self.api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n\n api_key = SecretStr(openai_api_key).get_secret_value() if openai_api_key else None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature if temperature is not None else 0.1,\n seed=seed,\n )\n if json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n SliderInput(\n name=\"temperature\", display_name=\"Temperature\", value=0.1, range_spec=RangeSpec(min=0, max=2, step=0.01)\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n openai_api_key = self.api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n\n api_key = SecretStr(openai_api_key).get_secret_value() if openai_api_key else None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature if temperature is not None else 0.1,\n seed=seed,\n )\n if json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n" }, "input_value": { "_input_type": "MessageInput", @@ -627,7 +953,9 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -775,7 +1103,9 @@ "display_name": "System Message", "dynamic": false, "info": "System message to pass to the model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "system_message", @@ -835,17 +1165,23 @@ "display_name": "Prompt", "id": "Prompt-lqX5p", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["post"] + "template": [ + "post" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -854,35 +1190,37 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "prompt", + "cache": true, "display_name": "Prompt Message", "method": "build_prompt", - "value": "__UNDEFINED__", - "cache": true + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n" }, "post": { "advanced": false, @@ -892,7 +1230,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -928,7 +1269,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -972,7 +1315,9 @@ "display_name": "Chat Output", "id": "ChatOutput-CnabR", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -998,13 +1343,15 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "message", + "cache": true, "display_name": "Message", "method": "message_response", - "value": "__UNDEFINED__", - "cache": true + "name": "message", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -1016,7 +1363,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -1036,7 +1385,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -1051,22 +1402,22 @@ "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\nfrom langflow.schema.properties import Source\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_AI,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatOutput\"\n minimized = True\n\n inputs = [\n MessageInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_AI,\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_AI,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(\n display_name=\"Message\",\n name=\"message\",\n method=\"message_response\",\n ),\n ]\n\n def _build_source(self, id_: str | None, display_name: str | None, source: str | None) -> Source:\n source_dict = {}\n if id_:\n source_dict[\"id\"] = id_\n if display_name:\n source_dict[\"display_name\"] = display_name\n if source:\n source_dict[\"source\"] = source\n return Source(**source_dict)\n\n async def message_response(self) -> Message:\n source, icon, display_name, source_id = self.get_properties_from_source_component()\n background_color = self.background_color\n text_color = self.text_color\n if self.chat_icon:\n icon = self.chat_icon\n message = self.input_value if isinstance(self.input_value, Message) else Message(text=self.input_value)\n message.sender = self.sender\n message.sender_name = self.sender_name\n message.session_id = self.session_id\n message.flow_id = self.graph.flow_id if hasattr(self, \"graph\") else None\n message.properties.source = self._build_source(source_id, display_name, source)\n message.properties.icon = icon\n message.properties.background_color = background_color\n message.properties.text_color = text_color\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\nfrom langflow.schema.properties import Source\nfrom langflow.utils.constants import (\n MESSAGE_SENDER_AI,\n MESSAGE_SENDER_NAME_AI,\n MESSAGE_SENDER_USER,\n)\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"MessagesSquare\"\n name = \"ChatOutput\"\n minimized = True\n\n inputs = [\n MessageInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_AI,\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_AI,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n MessageTextInput(\n name=\"background_color\",\n display_name=\"Background Color\",\n info=\"The background color of the icon.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"chat_icon\",\n display_name=\"Icon\",\n info=\"The icon of the message.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"text_color\",\n display_name=\"Text Color\",\n info=\"The text color of the name\",\n advanced=True,\n ),\n ]\n outputs = [\n Output(\n display_name=\"Message\",\n name=\"message\",\n method=\"message_response\",\n ),\n ]\n\n def _build_source(self, id_: str | None, display_name: str | None, source: str | None) -> Source:\n source_dict = {}\n if id_:\n source_dict[\"id\"] = id_\n if display_name:\n source_dict[\"display_name\"] = display_name\n if source:\n source_dict[\"source\"] = source\n return Source(**source_dict)\n\n async def message_response(self) -> Message:\n source, icon, display_name, source_id = self.get_properties_from_source_component()\n background_color = self.background_color\n text_color = self.text_color\n if self.chat_icon:\n icon = self.chat_icon\n message = self.input_value if isinstance(self.input_value, Message) else Message(text=self.input_value)\n message.sender = self.sender\n message.sender_name = self.sender_name\n message.session_id = self.session_id\n message.flow_id = self.graph.flow_id if hasattr(self, \"graph\") else None\n message.properties.source = self._build_source(source_id, display_name, source)\n message.properties.icon = icon\n message.properties.background_color = background_color\n message.properties.text_color = text_color\n if self.session_id and isinstance(message, Message) and self.should_store_message:\n stored_message = await self.send_message(\n message,\n )\n self.message.value = stored_message\n message = stored_message\n\n self.status = message\n return message\n" }, "data_template": { "_input_type": "MessageTextInput", @@ -1074,7 +1425,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -1094,7 +1447,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1115,7 +1470,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -1131,7 +1489,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1151,7 +1511,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1187,7 +1549,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -1231,7 +1595,9 @@ "display_name": "Agent", "id": "Agent-TG1G2", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1274,13 +1640,15 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "response", + "cache": true, "display_name": "Response", "method": "message_response", - "value": "__UNDEFINED__", - "cache": true + "name": "response", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -1308,7 +1676,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1357,7 +1727,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -1369,22 +1741,22 @@ "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langchain_core.tools import StructuredTool\n\nfrom langflow.base.agents.agent import LCToolsAgentComponent\nfrom langflow.base.models.model_input_constants import (\n ALL_PROVIDER_FIELDS,\n MODEL_DYNAMIC_UPDATE_FIELDS,\n MODEL_PROVIDERS_DICT,\n)\nfrom langflow.base.models.model_utils import get_model_name\nfrom langflow.components.helpers import CurrentDateComponent\nfrom langflow.components.helpers.memory import MemoryComponent\nfrom langflow.components.langchain_utilities.tool_calling import (\n ToolCallingAgentComponent,\n)\nfrom langflow.custom.utils import update_component_build_config\nfrom langflow.io import BoolInput, DropdownInput, MultilineInput, Output\nfrom langflow.logging import logger\nfrom langflow.schema.dotdict import dotdict\nfrom langflow.schema.message import Message\n\n\ndef set_advanced_true(component_input):\n component_input.advanced = True\n return component_input\n\n\nclass AgentComponent(ToolCallingAgentComponent):\n display_name: str = \"Agent\"\n description: str = \"Define the agent's instructions, then enter a task to complete using tools.\"\n icon = \"bot\"\n beta = False\n name = \"Agent\"\n\n memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs]\n\n inputs = [\n DropdownInput(\n name=\"agent_llm\",\n display_name=\"Model Provider\",\n info=\"The provider of the language model that the agent will use to generate responses.\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"OpenAI\",\n real_time_refresh=True,\n input_types=[],\n ),\n *MODEL_PROVIDERS_DICT[\"OpenAI\"][\"inputs\"],\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Agent Instructions\",\n info=\"System Prompt: Initial instructions and context provided to guide the agent's behavior.\",\n value=\"You are a helpful assistant that can use tools to answer questions and perform tasks.\",\n advanced=False,\n ),\n *LCToolsAgentComponent._base_inputs,\n *memory_inputs,\n BoolInput(\n name=\"add_current_date_tool\",\n display_name=\"Current Date\",\n advanced=True,\n info=\"If true, will add a tool to the agent that returns the current date.\",\n value=True,\n ),\n ]\n outputs = [Output(name=\"response\", display_name=\"Response\", method=\"message_response\")]\n\n async def message_response(self) -> Message:\n try:\n llm_model, display_name = self.get_llm()\n if llm_model is None:\n msg = \"No language model selected\"\n raise ValueError(msg)\n self.model_name = get_model_name(llm_model, display_name=display_name)\n except Exception as e:\n # Log the error for debugging purposes\n logger.error(f\"Error retrieving language model: {e}\")\n raise\n\n try:\n self.chat_history = await self.get_memory_data()\n except Exception as e:\n logger.error(f\"Error retrieving chat history: {e}\")\n raise\n\n if self.add_current_date_tool:\n try:\n if not isinstance(self.tools, list): # type: ignore[has-type]\n self.tools = []\n # Convert CurrentDateComponent to a StructuredTool\n current_date_tool = (await CurrentDateComponent().to_toolkit()).pop(0)\n # current_date_tool = CurrentDateComponent().to_toolkit()[0]\n if isinstance(current_date_tool, StructuredTool):\n self.tools.append(current_date_tool)\n else:\n msg = \"CurrentDateComponent must be converted to a StructuredTool\"\n raise TypeError(msg)\n except Exception as e:\n logger.error(f\"Error adding current date tool: {e}\")\n raise\n\n if not self.tools:\n msg = \"Tools are required to run the agent.\"\n logger.error(msg)\n raise ValueError(msg)\n\n try:\n self.set(\n llm=llm_model,\n tools=self.tools,\n chat_history=self.chat_history,\n input_value=self.input_value,\n system_prompt=self.system_prompt,\n )\n agent = self.create_agent_runnable()\n except Exception as e:\n logger.error(f\"Error setting up the agent: {e}\")\n raise\n\n return await self.run_agent(agent)\n\n async def get_memory_data(self):\n memory_kwargs = {\n component_input.name: getattr(self, f\"{component_input.name}\") for component_input in self.memory_inputs\n }\n\n return await MemoryComponent().set(**memory_kwargs).retrieve_messages()\n\n def get_llm(self):\n if isinstance(self.agent_llm, str):\n try:\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n display_name = component_class.display_name\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\", \"\")\n return (\n self._build_llm_model(component_class, inputs, prefix),\n display_name,\n )\n except Exception as e:\n msg = f\"Error building {self.agent_llm} language model\"\n raise ValueError(msg) from e\n return self.agent_llm, None\n\n def _build_llm_model(self, component, inputs, prefix=\"\"):\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n return component.set(**model_kwargs).build_model()\n\n def set_component_params(self, component):\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\")\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n\n return component.set(**model_kwargs)\n return component\n\n def delete_fields(self, build_config: dotdict, fields: dict | list[str]) -> None:\n \"\"\"Delete specified fields from build_config.\"\"\"\n for field in fields:\n build_config.pop(field, None)\n\n def update_input_types(self, build_config: dotdict) -> dotdict:\n \"\"\"Update input types for all fields in build_config.\"\"\"\n for key, value in build_config.items():\n if isinstance(value, dict):\n if value.get(\"input_types\") is None:\n build_config[key][\"input_types\"] = []\n elif hasattr(value, \"input_types\") and value.input_types is None:\n value.input_types = []\n return build_config\n\n async def update_build_config(\n self, build_config: dotdict, field_value: str, field_name: str | None = None\n ) -> dotdict:\n # Iterate over all providers in the MODEL_PROVIDERS_DICT\n # Existing logic for updating build_config\n if field_name in (\"agent_llm\",):\n provider_info = MODEL_PROVIDERS_DICT.get(field_value)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n if component_class and hasattr(component_class, \"update_build_config\"):\n # Call the component class's update_build_config method\n build_config = await update_component_build_config(\n component_class, build_config, field_value, field_name\n )\n\n provider_configs: dict[str, tuple[dict, list[dict]]] = {\n provider: (\n MODEL_PROVIDERS_DICT[provider][\"fields\"],\n [\n MODEL_PROVIDERS_DICT[other_provider][\"fields\"]\n for other_provider in MODEL_PROVIDERS_DICT\n if other_provider != provider\n ],\n )\n for provider in MODEL_PROVIDERS_DICT\n }\n if field_value in provider_configs:\n fields_to_add, fields_to_delete = provider_configs[field_value]\n\n # Delete fields from other providers\n for fields in fields_to_delete:\n self.delete_fields(build_config, fields)\n\n # Add provider-specific fields\n if field_value == \"OpenAI\" and not any(field in build_config for field in fields_to_add):\n build_config.update(fields_to_add)\n else:\n build_config.update(fields_to_add)\n # Reset input types for agent_llm\n build_config[\"agent_llm\"][\"input_types\"] = []\n elif field_value == \"Custom\":\n # Delete all provider fields\n self.delete_fields(build_config, ALL_PROVIDER_FIELDS)\n # Update with custom component\n custom_component = DropdownInput(\n name=\"agent_llm\",\n display_name=\"Language Model\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"Custom\",\n real_time_refresh=True,\n input_types=[\"LanguageModel\"],\n )\n build_config.update({\"agent_llm\": custom_component.to_dict()})\n # Update input types for all fields\n build_config = self.update_input_types(build_config)\n\n # Validate required keys\n default_keys = [\n \"code\",\n \"_type\",\n \"agent_llm\",\n \"tools\",\n \"input_value\",\n \"add_current_date_tool\",\n \"system_prompt\",\n \"agent_description\",\n \"max_iterations\",\n \"handle_parsing_errors\",\n \"verbose\",\n ]\n missing_keys = [key for key in default_keys if key not in build_config]\n if missing_keys:\n msg = f\"Missing required keys in build_config: {missing_keys}\"\n raise ValueError(msg)\n if (\n isinstance(self.agent_llm, str)\n and self.agent_llm in MODEL_PROVIDERS_DICT\n and field_name in MODEL_DYNAMIC_UPDATE_FIELDS\n ):\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n component_class = self.set_component_params(component_class)\n prefix = provider_info.get(\"prefix\")\n if component_class and hasattr(component_class, \"update_build_config\"):\n # Call each component class's update_build_config method\n # remove the prefix from the field_name\n if isinstance(field_name, str) and isinstance(prefix, str):\n field_name = field_name.replace(prefix, \"\")\n build_config = await update_component_build_config(\n component_class, build_config, field_value, field_name\n )\n return build_config\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langchain_core.tools import StructuredTool\n\nfrom langflow.base.agents.agent import LCToolsAgentComponent\nfrom langflow.base.models.model_input_constants import (\n ALL_PROVIDER_FIELDS,\n MODEL_DYNAMIC_UPDATE_FIELDS,\n MODEL_PROVIDERS_DICT,\n)\nfrom langflow.base.models.model_utils import get_model_name\nfrom langflow.components.helpers import CurrentDateComponent\nfrom langflow.components.helpers.memory import MemoryComponent\nfrom langflow.components.langchain_utilities.tool_calling import (\n ToolCallingAgentComponent,\n)\nfrom langflow.custom.utils import update_component_build_config\nfrom langflow.io import BoolInput, DropdownInput, MultilineInput, Output\nfrom langflow.logging import logger\nfrom langflow.schema.dotdict import dotdict\nfrom langflow.schema.message import Message\n\n\ndef set_advanced_true(component_input):\n component_input.advanced = True\n return component_input\n\n\nclass AgentComponent(ToolCallingAgentComponent):\n display_name: str = \"Agent\"\n description: str = \"Define the agent's instructions, then enter a task to complete using tools.\"\n icon = \"bot\"\n beta = False\n name = \"Agent\"\n\n memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs]\n\n inputs = [\n DropdownInput(\n name=\"agent_llm\",\n display_name=\"Model Provider\",\n info=\"The provider of the language model that the agent will use to generate responses.\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"OpenAI\",\n real_time_refresh=True,\n input_types=[],\n ),\n *MODEL_PROVIDERS_DICT[\"OpenAI\"][\"inputs\"],\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Agent Instructions\",\n info=\"System Prompt: Initial instructions and context provided to guide the agent's behavior.\",\n value=\"You are a helpful assistant that can use tools to answer questions and perform tasks.\",\n advanced=False,\n ),\n *LCToolsAgentComponent._base_inputs,\n *memory_inputs,\n BoolInput(\n name=\"add_current_date_tool\",\n display_name=\"Current Date\",\n advanced=True,\n info=\"If true, will add a tool to the agent that returns the current date.\",\n value=True,\n ),\n ]\n outputs = [Output(name=\"response\", display_name=\"Response\", method=\"message_response\")]\n\n async def message_response(self) -> Message:\n try:\n llm_model, display_name = self.get_llm()\n if llm_model is None:\n msg = \"No language model selected\"\n raise ValueError(msg)\n self.model_name = get_model_name(llm_model, display_name=display_name)\n except Exception as e:\n # Log the error for debugging purposes\n logger.error(f\"Error retrieving language model: {e}\")\n raise\n\n try:\n self.chat_history = await self.get_memory_data()\n except Exception as e:\n logger.error(f\"Error retrieving chat history: {e}\")\n raise\n\n if self.add_current_date_tool:\n try:\n if not isinstance(self.tools, list): # type: ignore[has-type]\n self.tools = []\n # Convert CurrentDateComponent to a StructuredTool\n current_date_tool = (await CurrentDateComponent().to_toolkit()).pop(0)\n # current_date_tool = CurrentDateComponent().to_toolkit()[0]\n if isinstance(current_date_tool, StructuredTool):\n self.tools.append(current_date_tool)\n else:\n msg = \"CurrentDateComponent must be converted to a StructuredTool\"\n raise TypeError(msg)\n except Exception as e:\n logger.error(f\"Error adding current date tool: {e}\")\n raise\n\n if not self.tools:\n msg = \"Tools are required to run the agent.\"\n logger.error(msg)\n raise ValueError(msg)\n\n try:\n self.set(\n llm=llm_model,\n tools=self.tools,\n chat_history=self.chat_history,\n input_value=self.input_value,\n system_prompt=self.system_prompt,\n )\n agent = self.create_agent_runnable()\n except Exception as e:\n logger.error(f\"Error setting up the agent: {e}\")\n raise\n\n return await self.run_agent(agent)\n\n async def get_memory_data(self):\n memory_kwargs = {\n component_input.name: getattr(self, f\"{component_input.name}\") for component_input in self.memory_inputs\n }\n\n return await MemoryComponent().set(**memory_kwargs).retrieve_messages()\n\n def get_llm(self):\n if isinstance(self.agent_llm, str):\n try:\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n display_name = component_class.display_name\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\", \"\")\n return (\n self._build_llm_model(component_class, inputs, prefix),\n display_name,\n )\n except Exception as e:\n msg = f\"Error building {self.agent_llm} language model\"\n raise ValueError(msg) from e\n return self.agent_llm, None\n\n def _build_llm_model(self, component, inputs, prefix=\"\"):\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n return component.set(**model_kwargs).build_model()\n\n def set_component_params(self, component):\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\")\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n\n return component.set(**model_kwargs)\n return component\n\n def delete_fields(self, build_config: dotdict, fields: dict | list[str]) -> None:\n \"\"\"Delete specified fields from build_config.\"\"\"\n for field in fields:\n build_config.pop(field, None)\n\n def update_input_types(self, build_config: dotdict) -> dotdict:\n \"\"\"Update input types for all fields in build_config.\"\"\"\n for key, value in build_config.items():\n if isinstance(value, dict):\n if value.get(\"input_types\") is None:\n build_config[key][\"input_types\"] = []\n elif hasattr(value, \"input_types\") and value.input_types is None:\n value.input_types = []\n return build_config\n\n async def update_build_config(\n self, build_config: dotdict, field_value: str, field_name: str | None = None\n ) -> dotdict:\n # Iterate over all providers in the MODEL_PROVIDERS_DICT\n # Existing logic for updating build_config\n if field_name in (\"agent_llm\",):\n provider_info = MODEL_PROVIDERS_DICT.get(field_value)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n if component_class and hasattr(component_class, \"update_build_config\"):\n # Call the component class's update_build_config method\n build_config = await update_component_build_config(\n component_class, build_config, field_value, field_name\n )\n\n provider_configs: dict[str, tuple[dict, list[dict]]] = {\n provider: (\n MODEL_PROVIDERS_DICT[provider][\"fields\"],\n [\n MODEL_PROVIDERS_DICT[other_provider][\"fields\"]\n for other_provider in MODEL_PROVIDERS_DICT\n if other_provider != provider\n ],\n )\n for provider in MODEL_PROVIDERS_DICT\n }\n if field_value in provider_configs:\n fields_to_add, fields_to_delete = provider_configs[field_value]\n\n # Delete fields from other providers\n for fields in fields_to_delete:\n self.delete_fields(build_config, fields)\n\n # Add provider-specific fields\n if field_value == \"OpenAI\" and not any(field in build_config for field in fields_to_add):\n build_config.update(fields_to_add)\n else:\n build_config.update(fields_to_add)\n # Reset input types for agent_llm\n build_config[\"agent_llm\"][\"input_types\"] = []\n elif field_value == \"Custom\":\n # Delete all provider fields\n self.delete_fields(build_config, ALL_PROVIDER_FIELDS)\n # Update with custom component\n custom_component = DropdownInput(\n name=\"agent_llm\",\n display_name=\"Language Model\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"Custom\",\n real_time_refresh=True,\n input_types=[\"LanguageModel\"],\n )\n build_config.update({\"agent_llm\": custom_component.to_dict()})\n # Update input types for all fields\n build_config = self.update_input_types(build_config)\n\n # Validate required keys\n default_keys = [\n \"code\",\n \"_type\",\n \"agent_llm\",\n \"tools\",\n \"input_value\",\n \"add_current_date_tool\",\n \"system_prompt\",\n \"agent_description\",\n \"max_iterations\",\n \"handle_parsing_errors\",\n \"verbose\",\n ]\n missing_keys = [key for key in default_keys if key not in build_config]\n if missing_keys:\n msg = f\"Missing required keys in build_config: {missing_keys}\"\n raise ValueError(msg)\n if (\n isinstance(self.agent_llm, str)\n and self.agent_llm in MODEL_PROVIDERS_DICT\n and field_name in MODEL_DYNAMIC_UPDATE_FIELDS\n ):\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n component_class = self.set_component_params(component_class)\n prefix = provider_info.get(\"prefix\")\n if component_class and hasattr(component_class, \"update_build_config\"):\n # Call each component class's update_build_config method\n # remove the prefix from the field_name\n if isinstance(field_name, str) and isinstance(prefix, str):\n field_name = field_name.replace(prefix, \"\")\n build_config = await update_component_build_config(\n component_class, build_config, field_value, field_name\n )\n return build_config\n" }, "handle_parsing_errors": { "_input_type": "BoolInput", @@ -1408,7 +1780,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1482,7 +1856,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -1576,7 +1952,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -1610,7 +1989,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -1626,7 +2009,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1646,7 +2031,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1666,7 +2053,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1703,7 +2092,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1724,7 +2115,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -1781,7 +2174,10 @@ "display_name": "OpenAI", "id": "OpenAIModel-Sef2w", "node": { - "base_classes": ["LanguageModel", "Message"], + "base_classes": [ + "LanguageModel", + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1812,24 +2208,28 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "text_output", + "cache": true, "display_name": "Message", "method": "text_response", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] + "name": "text_output", + "required_inputs": [], + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" }, { - "types": ["LanguageModel"], - "selected": "LanguageModel", - "name": "model_output", + "cache": true, "display_name": "Language Model", "method": "build_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] + "name": "model_output", + "required_inputs": [], + "selected": "LanguageModel", + "types": [ + "LanguageModel" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -1841,7 +2241,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -1853,22 +2255,22 @@ "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n SliderInput(\n name=\"temperature\", display_name=\"Temperature\", value=0.1, range_spec=RangeSpec(min=0, max=2, step=0.01)\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n openai_api_key = self.api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n\n api_key = SecretStr(openai_api_key).get_secret_value() if openai_api_key else None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature if temperature is not None else 0.1,\n seed=seed,\n )\n if json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.inputs import BoolInput, DictInput, DropdownInput, IntInput, SecretStrInput, SliderInput, StrInput\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = [\n *LCModelComponent._base_inputs,\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(\n name=\"model_kwargs\",\n display_name=\"Model Kwargs\",\n advanced=True,\n info=\"Additional keyword arguments to pass to the model.\",\n ),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. \"\n \"Defaults to https://api.openai.com/v1. \"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n SliderInput(\n name=\"temperature\", display_name=\"Temperature\", value=0.1, range_spec=RangeSpec(min=0, max=2, step=0.01)\n ),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n openai_api_key = self.api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = self.json_mode\n seed = self.seed\n\n api_key = SecretStr(openai_api_key).get_secret_value() if openai_api_key else None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature if temperature is not None else 0.1,\n seed=seed,\n )\n if json_mode:\n output = output.bind(response_format={\"type\": \"json_object\"})\n\n return output\n\n def _get_exception_message(self, e: Exception):\n \"\"\"Get a message from an OpenAI exception.\n\n Args:\n e (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n try:\n from openai import BadRequestError\n except ImportError:\n return None\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\")\n if message:\n return message\n return None\n" }, "input_value": { "_input_type": "MessageInput", @@ -1876,7 +2278,9 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -2024,7 +2428,9 @@ "display_name": "System Message", "dynamic": false, "info": "System message to pass to the model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "system_message", @@ -2084,17 +2490,24 @@ "display_name": "Prompt", "id": "Prompt-R2EK8", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["post", "image_description"] + "template": [ + "post", + "image_description" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -2103,35 +2516,37 @@ "output_types": [], "outputs": [ { - "types": ["Message"], - "selected": "Message", - "name": "prompt", + "cache": true, "display_name": "Prompt Message", "method": "build_prompt", - "value": "__UNDEFINED__", - "cache": true + "name": "prompt", + "selected": "Message", + "types": [ + "Message" + ], + "value": "__UNDEFINED__" } ], "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import MessageTextInput, Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n MessageTextInput(\n name=\"tool_placeholder\",\n display_name=\"Tool Placeholder\",\n tool_mode=True,\n advanced=True,\n info=\"A placeholder input for tool mode.\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(self) -> Message:\n prompt = Message.from_template(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n async def update_frontend_node(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"This function is called after the code validation is done.\"\"\"\n frontend_node = await super().update_frontend_node(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n" }, "image_description": { "advanced": false, @@ -2141,7 +2556,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2161,7 +2579,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2197,7 +2618,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -2405,7 +2828,10 @@ "data": { "id": "TavilySearchComponent-xQwoJ", "node": { - "base_classes": ["Data", "Message"], + "base_classes": [ + "Data", + "Message" + ], "beta": false, "category": "tools", "conditional_paths": [], @@ -2432,15 +2858,17 @@ "output_types": [], "outputs": [ { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", "cache": true, - "required_inputs": null + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -2453,7 +2881,9 @@ "display_name": "Tavily API Key", "dynamic": false, "info": "Your Tavily API Key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -2542,7 +2972,9 @@ "display_name": "Search Query", "dynamic": false, "info": "The search query you want to execute with Tavily.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "list_add_label": "Add More", "load_from_db": false, @@ -2565,7 +2997,10 @@ "dynamic": false, "info": "The depth of the search.", "name": "search_depth", - "options": ["basic", "advanced"], + "options": [ + "basic", + "advanced" + ], "placeholder": "", "required": false, "show": true, @@ -2576,89 +3011,96 @@ "value": "advanced" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, "table_icon": "Hammer", "table_options": { "block_add": true, "block_delete": true, "block_edit": true, - "block_sort": true, "block_filter": true, "block_hide": true, "block_select": true, - "hide_options": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." + "hide_options": true }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { "description": "fetch_content(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", "name": "None-fetch_content", - "tags": ["None-fetch_content"] + "tags": [ + "None-fetch_content" + ] }, { "description": "fetch_content_text(api_key: Message) - **Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", "name": "None-fetch_content_text", - "tags": ["None-fetch_content_text"] + "tags": [ + "None-fetch_content_text" + ] } - ], - "display_name": "Edit tools", - "advanced": false, - "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" + ] }, "topic": { "_input_type": "DropdownInput", @@ -2668,7 +3110,10 @@ "dynamic": false, "info": "The category of the search.", "name": "topic", - "options": ["general", "news"], + "options": [ + "general", + "news" + ], "placeholder": "", "required": false, "show": true, @@ -2698,236 +3143,6 @@ "type": "genericNode" } ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TextInput", - "id": "TextInput-0rzBn", - "name": "text", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "guidelines", - "id": "Prompt-j3woL", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-TextInput-0rzBn{œdataTypeœ:œTextInputœ,œidœ:œTextInput-0rzBnœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-j3woL{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "TextInput-0rzBn", - "sourceHandle": "{œdataTypeœ:œTextInputœ,œidœ:œTextInput-0rzBnœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-j3woL", - "targetHandle": "{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-jxXfH", - "name": "text_output", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-lqX5p", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-jxXfH{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-lqX5p{œfieldNameœ:œpostœ,œidœ:œPrompt-lqX5pœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-jxXfH", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-lqX5p", - "targetHandle": "{œfieldNameœ:œpostœ,œidœ:œPrompt-lqX5pœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-j3woL", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-jxXfH", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-j3woL{œdataTypeœ:œPromptœ,œidœ:œPrompt-j3woLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-jxXfH{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-jxXfHœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-j3woL", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-j3woLœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-jxXfH", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-jxXfHœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-pvWq5", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-TG1G2", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-pvWq5{œdataTypeœ:œChatInputœ,œidœ:œChatInput-pvWq5œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-TG1G2{œfieldNameœ:œinput_valueœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-pvWq5", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-pvWq5œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-TG1G2", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-TG1G2", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-j3woL", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-TG1G2{œdataTypeœ:œAgentœ,œidœ:œAgent-TG1G2œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-j3woL{œfieldNameœ:œcontextœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-TG1G2", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-TG1G2œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-j3woL", - "targetHandle": "{œfieldNameœ:œcontextœ,œidœ:œPrompt-j3woLœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-lqX5p", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-Sef2w", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-lqX5p{œdataTypeœ:œPromptœ,œidœ:œPrompt-lqX5pœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-Sef2w{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Sef2wœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-lqX5p", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-lqX5pœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-Sef2w", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Sef2wœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-jxXfH", - "name": "text_output", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-R2EK8", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-jxXfH{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-R2EK8{œfieldNameœ:œpostœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-jxXfH", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-jxXfHœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-R2EK8", - "targetHandle": "{œfieldNameœ:œpostœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": true, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-Sef2w", - "name": "text_output", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "image_description", - "id": "Prompt-R2EK8", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-Sef2w{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Sef2wœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-R2EK8{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-Sef2w", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Sef2wœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-R2EK8", - "targetHandle": "{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-R2EK8œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-R2EK8", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-CnabR", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-R2EK8{œdataTypeœ:œPromptœ,œidœ:œPrompt-R2EK8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-CnabR{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-CnabRœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-R2EK8", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-R2EK8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-CnabR", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-CnabRœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "source": "TavilySearchComponent-xQwoJ", - "sourceHandle": "{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-xQwoJœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-TG1G2", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-TG1G2", - "inputTypes": ["Tool"], - "type": "other" - }, - "sourceHandle": { - "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-xQwoJ", - "name": "component_as_tool", - "output_types": ["Tool"] - } - }, - "id": "xy-edge__TavilySearchComponent-xQwoJ{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-xQwoJœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-TG1G2{œfieldNameœ:œtoolsœ,œidœ:œAgent-TG1G2œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - } - ], "viewport": { "x": -1462.1369874897664, "y": -557.4373796474765, @@ -2942,5 +3157,9 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Instagram Copywriter", - "tags": ["content-generation", "chatbots", "agents"] -} + "tags": [ + "content-generation", + "chatbots", + "agents" + ] +} \ No newline at end of file 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 4d5e3dda0..0eee50dad 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 @@ -1,5 +1,287 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-wWNhZ", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "previous_response", + "id": "Prompt-MTcxq", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-wWNhZ{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-wWNhZœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-MTcxq{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-MTcxqœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "selected": false, + "source": "OpenAIModel-wWNhZ", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-wWNhZœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-MTcxq", + "targetHandle": "{œfieldNameœ: œprevious_responseœ, œidœ: œPrompt-MTcxqœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-hBw61", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-ILQV8", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-hBw61{œdataTypeœ:œPromptœ,œidœ:œPrompt-hBw61œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-ILQV8{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Prompt-hBw61", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-hBw61œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-ILQV8", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-ILQV8œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-YWCg2", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Prompt-hBw61", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-YWCg2{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-hBw61{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-YWCg2", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-YWCg2œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-hBw61", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œPrompt-hBw61œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-ILQV8", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-jGyp6", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-ILQV8{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-ILQV8œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-jGyp6{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jGyp6œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "OpenAIModel-ILQV8", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-ILQV8œ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-jGyp6", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-jGyp6œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "TavilyAISearch", + "id": "TavilyAISearch-wu6YR", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-lD2aY", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-TavilyAISearch-wu6YR{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-wu6YRœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-lD2aY{œfieldNameœ:œtoolsœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "selected": false, + "source": "TavilyAISearch-wu6YR", + "sourceHandle": "{œdataTypeœ: œTavilyAISearchœ, œidœ: œTavilyAISearch-wu6YRœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-lD2aY", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-lD2aYœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-MTcxq", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-lD2aY", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-MTcxq{œdataTypeœ:œPromptœ,œidœ:œPrompt-MTcxqœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-lD2aY{œfieldNameœ:œinput_valueœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Prompt-MTcxq", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-MTcxqœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-lD2aY", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-lD2aYœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-lD2aY", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "search_results", + "id": "Prompt-hBw61", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-lD2aY{œdataTypeœ:œAgentœ,œidœ:œAgent-lD2aYœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-hBw61{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Agent-lD2aY", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-lD2aYœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-hBw61", + "targetHandle": "{œfieldNameœ: œsearch_resultsœ, œidœ: œPrompt-hBw61œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-Unjx8", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_message", + "id": "OpenAIModel-wWNhZ", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-Unjx8{œdataTypeœ:œPromptœ,œidœ:œPrompt-Unjx8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-wWNhZ{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-Unjx8", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Unjx8œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-wWNhZ", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-wWNhZœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-YWCg2", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-wWNhZ", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-YWCg2{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-wWNhZ{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-YWCg2", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-YWCg2œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-wWNhZ", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-wWNhZœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-U0O7D", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_message", + "id": "OpenAIModel-ILQV8", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-U0O7D{œdataTypeœ:œPromptœ,œidœ:œPrompt-U0O7Dœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-ILQV8{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-U0O7D", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-U0O7Dœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-ILQV8", + "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-ILQV8œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], "nodes": [ { "data": { @@ -7,17 +289,23 @@ "display_name": "Prompt", "id": "Prompt-MTcxq", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["previous_response"] + "template": [ + "previous_response" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -31,7 +319,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -64,7 +354,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -100,7 +393,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -122,6 +417,10 @@ "dragging": false, "height": 347, "id": "Prompt-MTcxq", + "measured": { + "height": 347, + "width": 320 + }, "position": { "x": 1803.2315476328304, "y": 839.0423490089254 @@ -132,17 +431,15 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 347 - } + "width": 320 }, { "data": { "id": "ChatInput-YWCg2", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "category": "inputs", "conditional_paths": [], @@ -176,7 +473,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -189,7 +488,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -208,7 +509,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -309,7 +612,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -324,7 +630,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -343,7 +651,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -378,7 +688,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -398,6 +710,10 @@ "dragging": false, "height": 234, "id": "ChatInput-YWCg2", + "measured": { + "height": 234, + "width": 320 + }, "position": { "x": 756.0075981758582, "y": 756.7423476254241 @@ -408,11 +724,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 234 - } + "width": 320 }, { "data": { @@ -420,7 +732,9 @@ "display_name": "Chat Output", "id": "ChatOutput-jGyp6", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -452,7 +766,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -465,7 +781,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -485,7 +803,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -523,7 +843,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -543,7 +865,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -564,7 +888,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -580,7 +907,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -600,7 +929,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -636,7 +967,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -658,6 +991,10 @@ "dragging": false, "height": 234, "id": "ChatOutput-jGyp6", + "measured": { + "height": 234, + "width": 320 + }, "position": { "x": 3200.774558432761, "y": 853.9881404769172 @@ -668,11 +1005,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 234 - } + "width": 320 }, { "data": { @@ -680,17 +1013,24 @@ "display_name": "Prompt", "id": "Prompt-hBw61", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["search_results", "input_value"] + "template": [ + "search_results", + "input_value" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -704,7 +1044,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -737,7 +1079,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -757,7 +1102,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -793,7 +1141,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -815,6 +1165,10 @@ "dragging": false, "height": 433, "id": "Prompt-hBw61", + "measured": { + "height": 433, + "width": 320 + }, "position": { "x": 2504.138359606453, "y": 434.061360540584 @@ -825,11 +1179,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 433 - } + "width": 320 }, { "data": { @@ -837,190 +1187,17 @@ "display_name": "Tavily AI Search [DEPRECATED]", "id": "TavilyAISearch-wu6YR", "node": { - "template": { - "_type": "Component", - "api_key": { - "load_from_db": true, - "required": true, - "placeholder": "", - "show": true, - "name": "api_key", - "value": "", - "display_name": "Tavily API Key", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "Your Tavily API Key.", - "title_case": false, - "password": true, - "type": "str", - "_input_type": "SecretStrInput" - }, - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from enum import Enum\n\nimport httpx\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass TavilySearchDepth(Enum):\n BASIC = \"basic\"\n ADVANCED = \"advanced\"\n\n\nclass TavilySearchTopic(Enum):\n GENERAL = \"general\"\n NEWS = \"news\"\n\n\nclass TavilySearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query you want to execute with Tavily.\")\n search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description=\"The depth of the search.\")\n topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description=\"The category of the search.\")\n max_results: int = Field(5, description=\"The maximum number of search results to return.\")\n include_images: bool = Field(default=False, description=\"Include a list of query-related images in the response.\")\n include_answer: bool = Field(default=False, description=\"Include a short answer to original query.\")\n\n\nclass TavilySearchToolComponent(LCToolComponent):\n display_name = \"Tavily AI Search [DEPRECATED]\"\n description = \"\"\"**Tavily AI** is a search engine optimized for LLMs and RAG, \\\n aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n\"\"\"\n icon = \"TavilyIcon\"\n name = \"TavilyAISearch\"\n documentation = \"https://docs.tavily.com/\"\n legacy = True\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Tavily API Key\",\n required=True,\n info=\"Your Tavily API Key.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The search query you want to execute with Tavily.\",\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=list(TavilySearchDepth),\n value=TavilySearchDepth.ADVANCED,\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=list(TavilySearchTopic),\n value=TavilySearchTopic.GENERAL,\n advanced=True,\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"The maximum number of search results to return.\",\n value=5,\n advanced=True,\n ),\n BoolInput(\n name=\"include_images\",\n display_name=\"Include Images\",\n info=\"Include a list of query-related images in the response.\",\n value=True,\n advanced=True,\n ),\n BoolInput(\n name=\"include_answer\",\n display_name=\"Include Answer\",\n info=\"Include a short answer to original query.\",\n value=True,\n advanced=True,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n # Convert string values to enum instances with validation\n try:\n search_depth_enum = (\n self.search_depth\n if isinstance(self.search_depth, TavilySearchDepth)\n else TavilySearchDepth(str(self.search_depth).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid search depth value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n try:\n topic_enum = (\n self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid topic value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n return self._tavily_search(\n self.query,\n search_depth=search_depth_enum,\n topic=topic_enum,\n max_results=self.max_results,\n include_images=self.include_images,\n include_answer=self.include_answer,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"tavily_search\",\n description=\"Perform a web search using the Tavily API.\",\n func=self._tavily_search,\n args_schema=TavilySearchSchema,\n )\n\n def _tavily_search(\n self,\n query: str,\n *,\n search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,\n topic: TavilySearchTopic = TavilySearchTopic.GENERAL,\n max_results: int = 5,\n include_images: bool = False,\n include_answer: bool = False,\n ) -> list[Data]:\n # Validate enum values\n if not isinstance(search_depth, TavilySearchDepth):\n msg = f\"Invalid search_depth value: {search_depth}\"\n raise TypeError(msg)\n if not isinstance(topic, TavilySearchTopic):\n msg = f\"Invalid topic value: {topic}\"\n raise TypeError(msg)\n\n try:\n url = \"https://api.tavily.com/search\"\n headers = {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json\",\n }\n payload = {\n \"api_key\": self.api_key,\n \"query\": query,\n \"search_depth\": search_depth.value,\n \"topic\": topic.value,\n \"max_results\": max_results,\n \"include_images\": include_images,\n \"include_answer\": include_answer,\n }\n\n with httpx.Client() as client:\n response = client.post(url, json=payload, headers=headers)\n\n response.raise_for_status()\n search_results = response.json()\n\n data_results = [\n Data(\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": result.get(\"content\"),\n \"score\": result.get(\"score\"),\n }\n )\n for result in search_results.get(\"results\", [])\n ]\n\n if include_answer and search_results.get(\"answer\"):\n data_results.insert(0, Data(data={\"answer\": search_results[\"answer\"]}))\n\n if include_images and search_results.get(\"images\"):\n data_results.append(Data(data={\"images\": search_results[\"images\"]}))\n\n self.status = data_results # type: ignore[assignment]\n\n except httpx.HTTPStatusError as e:\n error_message = f\"HTTP error: {e.response.status_code} - {e.response.text}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.opt(exception=True).debug(\"Error running Tavily Search\")\n self.status = error_message\n raise ToolException(error_message) from e\n return data_results\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "include_answer": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "include_answer", - "value": true, - "display_name": "Include Answer", - "advanced": true, - "dynamic": false, - "info": "Include a short answer to original query.", - "title_case": false, - "type": "bool", - "_input_type": "BoolInput" - }, - "include_images": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "include_images", - "value": true, - "display_name": "Include Images", - "advanced": true, - "dynamic": false, - "info": "Include a list of query-related images in the response.", - "title_case": false, - "type": "bool", - "_input_type": "BoolInput" - }, - "max_results": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "max_results", - "value": 5, - "display_name": "Max Results", - "advanced": true, - "dynamic": false, - "info": "The maximum number of search results to return.", - "title_case": false, - "type": "int", - "_input_type": "IntInput" - }, - "query": { - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "query", - "value": "", - "display_name": "Search Query", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "The search query you want to execute with Tavily.", - "title_case": false, - "type": "str", - "_input_type": "MessageTextInput" - }, - "search_depth": { - "tool_mode": false, - "trace_as_metadata": true, - "options": ["basic", "advanced"], - "combobox": false, - "required": false, - "placeholder": "", - "show": true, - "name": "search_depth", - "value": "advanced", - "display_name": "Search Depth", - "advanced": true, - "dynamic": false, - "info": "The depth of the search.", - "title_case": false, - "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false - }, - "topic": { - "tool_mode": false, - "trace_as_metadata": true, - "options": ["general", "news"], - "combobox": false, - "required": false, - "placeholder": "", - "show": true, - "name": "topic", - "value": "general", - "display_name": "Search Topic", - "advanced": true, - "dynamic": false, - "info": "The category of the search.", - "title_case": false, - "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false - } - }, + "base_classes": [ + "Data", + "Tool" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n", - "icon": "TavilyIcon", - "base_classes": ["Data", "Tool"], "display_name": "Tavily AI Search [DEPRECATED]", "documentation": "https://docs.tavily.com/", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Data"], - "selected": "Data", - "name": "api_run_model", - "display_name": "Data", - "method": "run_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - }, - { - "types": ["Tool"], - "selected": "Tool", - "name": "api_build_tool", - "display_name": "Tool", - "method": "build_tool", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - } - ], + "edited": false, "field_order": [ "api_key", "query", @@ -1030,10 +1207,204 @@ "include_images", "include_answer" ], - "beta": false, + "frozen": false, + "icon": "TavilyIcon", "legacy": true, - "edited": false, "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "method": "run_model", + "name": "api_run_model", + "required_inputs": [ + "api_key" + ], + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Tool", + "method": "build_tool", + "name": "api_build_tool", + "required_inputs": [ + "api_key" + ], + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "api_key": { + "_input_type": "SecretStrInput", + "advanced": false, + "display_name": "Tavily API Key", + "dynamic": false, + "info": "Your Tavily API Key.", + "input_types": [ + "Message" + ], + "load_from_db": true, + "name": "api_key", + "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from enum import Enum\n\nimport httpx\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass TavilySearchDepth(Enum):\n BASIC = \"basic\"\n ADVANCED = \"advanced\"\n\n\nclass TavilySearchTopic(Enum):\n GENERAL = \"general\"\n NEWS = \"news\"\n\n\nclass TavilySearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query you want to execute with Tavily.\")\n search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description=\"The depth of the search.\")\n topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description=\"The category of the search.\")\n max_results: int = Field(5, description=\"The maximum number of search results to return.\")\n include_images: bool = Field(default=False, description=\"Include a list of query-related images in the response.\")\n include_answer: bool = Field(default=False, description=\"Include a short answer to original query.\")\n\n\nclass TavilySearchToolComponent(LCToolComponent):\n display_name = \"Tavily AI Search [DEPRECATED]\"\n description = \"\"\"**Tavily AI** is a search engine optimized for LLMs and RAG, \\\n aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n\"\"\"\n icon = \"TavilyIcon\"\n name = \"TavilyAISearch\"\n documentation = \"https://docs.tavily.com/\"\n legacy = True\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Tavily API Key\",\n required=True,\n info=\"Your Tavily API Key.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The search query you want to execute with Tavily.\",\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=list(TavilySearchDepth),\n value=TavilySearchDepth.ADVANCED,\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=list(TavilySearchTopic),\n value=TavilySearchTopic.GENERAL,\n advanced=True,\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"The maximum number of search results to return.\",\n value=5,\n advanced=True,\n ),\n BoolInput(\n name=\"include_images\",\n display_name=\"Include Images\",\n info=\"Include a list of query-related images in the response.\",\n value=True,\n advanced=True,\n ),\n BoolInput(\n name=\"include_answer\",\n display_name=\"Include Answer\",\n info=\"Include a short answer to original query.\",\n value=True,\n advanced=True,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n # Convert string values to enum instances with validation\n try:\n search_depth_enum = (\n self.search_depth\n if isinstance(self.search_depth, TavilySearchDepth)\n else TavilySearchDepth(str(self.search_depth).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid search depth value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n try:\n topic_enum = (\n self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid topic value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n return self._tavily_search(\n self.query,\n search_depth=search_depth_enum,\n topic=topic_enum,\n max_results=self.max_results,\n include_images=self.include_images,\n include_answer=self.include_answer,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"tavily_search\",\n description=\"Perform a web search using the Tavily API.\",\n func=self._tavily_search,\n args_schema=TavilySearchSchema,\n )\n\n def _tavily_search(\n self,\n query: str,\n *,\n search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,\n topic: TavilySearchTopic = TavilySearchTopic.GENERAL,\n max_results: int = 5,\n include_images: bool = False,\n include_answer: bool = False,\n ) -> list[Data]:\n # Validate enum values\n if not isinstance(search_depth, TavilySearchDepth):\n msg = f\"Invalid search_depth value: {search_depth}\"\n raise TypeError(msg)\n if not isinstance(topic, TavilySearchTopic):\n msg = f\"Invalid topic value: {topic}\"\n raise TypeError(msg)\n\n try:\n url = \"https://api.tavily.com/search\"\n headers = {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json\",\n }\n payload = {\n \"api_key\": self.api_key,\n \"query\": query,\n \"search_depth\": search_depth.value,\n \"topic\": topic.value,\n \"max_results\": max_results,\n \"include_images\": include_images,\n \"include_answer\": include_answer,\n }\n\n with httpx.Client() as client:\n response = client.post(url, json=payload, headers=headers)\n\n response.raise_for_status()\n search_results = response.json()\n\n data_results = [\n Data(\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": result.get(\"content\"),\n \"score\": result.get(\"score\"),\n }\n )\n for result in search_results.get(\"results\", [])\n ]\n\n if include_answer and search_results.get(\"answer\"):\n data_results.insert(0, Data(data={\"answer\": search_results[\"answer\"]}))\n\n if include_images and search_results.get(\"images\"):\n data_results.append(Data(data={\"images\": search_results[\"images\"]}))\n\n self.status = data_results # type: ignore[assignment]\n\n except httpx.HTTPStatusError as e:\n error_message = f\"HTTP error: {e.response.status_code} - {e.response.text}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.opt(exception=True).debug(\"Error running Tavily Search\")\n self.status = error_message\n raise ToolException(error_message) from e\n return data_results\n" + }, + "include_answer": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Answer", + "dynamic": false, + "info": "Include a short answer to original query.", + "list": false, + "list_add_label": "Add More", + "name": "include_answer", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "include_images": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Images", + "dynamic": false, + "info": "Include a list of query-related images in the response.", + "list": false, + "list_add_label": "Add More", + "name": "include_images", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "max_results": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Results", + "dynamic": false, + "info": "The maximum number of search results to return.", + "list": false, + "list_add_label": "Add More", + "name": "max_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 5 + }, + "query": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Search Query", + "dynamic": false, + "info": "The search query you want to execute with Tavily.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "query", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "search_depth": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "display_name": "Search Depth", + "dynamic": false, + "info": "The depth of the search.", + "load_from_db": false, + "name": "search_depth", + "options": [ + "basic", + "advanced" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "advanced" + }, + "topic": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "display_name": "Search Topic", + "dynamic": false, + "info": "The category of the search.", + "load_from_db": false, + "name": "topic", + "options": [ + "general", + "news" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "general" + } + }, "tool_mode": false }, "type": "TavilyAISearch" @@ -1041,6 +1412,10 @@ "dragging": false, "height": 481, "id": "TavilyAISearch-wu6YR", + "measured": { + "height": 481, + "width": 320 + }, "position": { "x": 1802.2291194402355, "y": 381.88177151343945 @@ -1051,11 +1426,7 @@ }, "selected": true, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 481 - } + "width": 320 }, { "data": { @@ -1063,7 +1434,10 @@ "display_name": "OpenAI", "id": "OpenAIModel-wWNhZ", "node": { - "base_classes": ["LanguageModel", "Message"], + "base_classes": [ + "LanguageModel", + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1100,7 +1474,9 @@ "name": "text_output", "required_inputs": [], "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" }, { @@ -1110,7 +1486,9 @@ "name": "model_output", "required_inputs": [], "selected": "LanguageModel", - "types": ["LanguageModel"], + "types": [ + "LanguageModel" + ], "value": "__UNDEFINED__" } ], @@ -1123,7 +1501,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -1158,7 +1538,9 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1306,7 +1688,9 @@ "display_name": "System Message", "dynamic": false, "info": "System message to pass to the model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "system_message", @@ -1344,6 +1728,10 @@ "dragging": false, "height": 630, "id": "OpenAIModel-wWNhZ", + "measured": { + "height": 630, + "width": 320 + }, "position": { "x": 1457.8987895868838, "y": 543.8838473503562 @@ -1354,11 +1742,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 630 - } + "width": 320 }, { "data": { @@ -1366,7 +1750,10 @@ "display_name": "OpenAI", "id": "OpenAIModel-ILQV8", "node": { - "base_classes": ["LanguageModel", "Message"], + "base_classes": [ + "LanguageModel", + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1403,7 +1790,9 @@ "name": "text_output", "required_inputs": [], "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" }, { @@ -1413,7 +1802,9 @@ "name": "model_output", "required_inputs": [], "selected": "LanguageModel", - "types": ["LanguageModel"], + "types": [ + "LanguageModel" + ], "value": "__UNDEFINED__" } ], @@ -1426,7 +1817,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -1461,7 +1854,9 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1609,7 +2004,9 @@ "display_name": "System Message", "dynamic": false, "info": "System message to pass to the model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "system_message", @@ -1647,6 +2044,10 @@ "dragging": false, "height": 630, "id": "OpenAIModel-ILQV8", + "measured": { + "height": 630, + "width": 320 + }, "position": { "x": 2860.2941186979524, "y": 561.8661152181708 @@ -1657,11 +2058,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 630 - } + "width": 320 }, { "data": { @@ -1679,6 +2076,10 @@ "dragging": false, "height": 765, "id": "note-kzU8Y", + "measured": { + "height": 765, + "width": 325 + }, "position": { "x": 471.4335708918645, "y": -9.732869247334605 @@ -1694,11 +2095,7 @@ "width": 600 }, "type": "noteNode", - "width": 600, - "measured": { - "width": 325, - "height": 765 - } + "width": 600 }, { "data": { @@ -1706,7 +2103,9 @@ "display_name": "Agent", "id": "Agent-lD2aY", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1755,7 +2154,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1784,7 +2185,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1833,7 +2236,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -1884,7 +2289,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1958,7 +2365,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -2052,7 +2461,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -2086,7 +2498,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -2102,7 +2518,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -2122,7 +2540,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -2142,7 +2562,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2179,7 +2601,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2200,7 +2624,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -2235,6 +2661,10 @@ "dragging": false, "height": 658, "id": "Agent-lD2aY", + "measured": { + "height": 658, + "width": 320 + }, "position": { "x": 2156.60686936856, "y": 439.4579572266066 @@ -2245,11 +2675,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 658 - } + "width": 320 }, { "data": { @@ -2257,7 +2683,9 @@ "display_name": "Prompt", "id": "Prompt-Unjx8", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { @@ -2267,7 +2695,9 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -2281,7 +2711,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -2330,7 +2762,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -2352,6 +2786,10 @@ "dragging": false, "height": 260, "id": "Prompt-Unjx8", + "measured": { + "height": 260, + "width": 320 + }, "position": { "x": 1102.6079408836365, "y": 550.2148817052229 @@ -2362,11 +2800,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 260 - } + "width": 320 }, { "data": { @@ -2374,7 +2808,9 @@ "display_name": "Prompt", "id": "Prompt-U0O7D", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { @@ -2384,7 +2820,9 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -2398,7 +2836,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -2447,7 +2887,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -2469,6 +2911,10 @@ "dragging": false, "height": 260, "id": "Prompt-U0O7D", + "measured": { + "height": 260, + "width": 320 + }, "position": { "x": 2498.9482347755306, "y": 889.7491088138673 @@ -2479,11 +2925,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 260 - } + "width": 320 }, { "data": { @@ -2501,6 +2943,10 @@ "dragging": false, "height": 325, "id": "note-ZeCGk", + "measured": { + "height": 325, + "width": 325 + }, "position": { "x": 1797.5781951055678, "y": 206.30509875543274 @@ -2511,250 +2957,7 @@ }, "selected": false, "type": "noteNode", - "width": 325, - "measured": { - "width": 325, - "height": 325 - } - } - ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-wWNhZ", - "name": "text_output", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "previous_response", - "id": "Prompt-MTcxq", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-wWNhZ{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-wWNhZœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-MTcxq{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-MTcxqœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-wWNhZ", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-wWNhZœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-MTcxq", - "targetHandle": "{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-MTcxqœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-hBw61", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-ILQV8", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-hBw61{œdataTypeœ:œPromptœ,œidœ:œPrompt-hBw61œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-ILQV8{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Prompt-hBw61", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-hBw61œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-ILQV8", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-YWCg2", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Prompt-hBw61", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-YWCg2{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-hBw61{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-YWCg2", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-hBw61", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-ILQV8", - "name": "text_output", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-jGyp6", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-ILQV8{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-ILQV8œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-jGyp6{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jGyp6œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-ILQV8", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-ILQV8œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-jGyp6", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jGyp6œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TavilyAISearch", - "id": "TavilyAISearch-wu6YR", - "name": "api_build_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-lD2aY", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-TavilyAISearch-wu6YR{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-wu6YRœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-lD2aY{œfieldNameœ:œtoolsœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "selected": false, - "source": "TavilyAISearch-wu6YR", - "sourceHandle": "{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-wu6YRœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-lD2aY", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-MTcxq", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-lD2aY", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-MTcxq{œdataTypeœ:œPromptœ,œidœ:œPrompt-MTcxqœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-lD2aY{œfieldNameœ:œinput_valueœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Prompt-MTcxq", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-MTcxqœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-lD2aY", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-lD2aYœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-lD2aY", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "search_results", - "id": "Prompt-hBw61", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-lD2aY{œdataTypeœ:œAgentœ,œidœ:œAgent-lD2aYœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-hBw61{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Agent-lD2aY", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-lD2aYœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-hBw61", - "targetHandle": "{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-hBw61œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-Unjx8", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-wWNhZ", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-Unjx8{œdataTypeœ:œPromptœ,œidœ:œPrompt-Unjx8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-wWNhZ{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-Unjx8", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-Unjx8œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-wWNhZ", - "targetHandle": "{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-YWCg2", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-wWNhZ", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-YWCg2{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-wWNhZ{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-YWCg2", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-YWCg2œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-wWNhZ", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-wWNhZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-U0O7D", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-ILQV8", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-U0O7D{œdataTypeœ:œPromptœ,œidœ:œPrompt-U0O7Dœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-ILQV8{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-U0O7D", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-U0O7Dœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-ILQV8", - "targetHandle": "{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-ILQV8œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" + "width": 325 } ], "viewport": { @@ -2771,5 +2974,8 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Research Agent", - "tags": ["assistants", "agents"] -} + "tags": [ + "assistants", + "agents" + ] +} \ No newline at end of file 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 ba1f2c39e..173087a62 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 @@ -1,5 +1,86 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-LDhCf", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-YQ7Vi", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-LDhCf{œdataTypeœ:œAgentœ,œidœ:œAgent-LDhCfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-YQ7Vi{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-YQ7Viœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-LDhCf", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-LDhCfœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-YQ7Vi", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-YQ7Viœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-Pe4nO", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-LDhCf", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-Pe4nO{œdataTypeœ:œPromptœ,œidœ:œPrompt-Pe4nOœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-LDhCf{œfieldNameœ:œinput_valueœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-Pe4nO", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-Pe4nOœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-LDhCf", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-LDhCfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "CalculatorComponent", + "id": "CalculatorComponent-unDLj", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-LDhCf", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__CalculatorComponent-unDLj{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-unDLjœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-LDhCf{œfieldNameœ:œtoolsœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "CalculatorComponent-unDLj", + "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-unDLjœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-LDhCf", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-LDhCfœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { @@ -7,7 +88,9 @@ "display_name": "Prompt", "id": "Prompt-Pe4nO", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { @@ -23,7 +106,9 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "icon": "prompts", "legacy": false, @@ -37,7 +122,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -70,7 +157,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -90,7 +180,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -110,7 +203,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -130,7 +226,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -150,7 +249,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -186,7 +288,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -230,7 +334,9 @@ "display_name": "Chat Output", "id": "ChatOutput-YQ7Vi", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -262,7 +368,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -275,7 +383,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -295,7 +405,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -333,7 +445,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -353,7 +467,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -374,7 +490,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -390,7 +509,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -410,7 +531,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -446,7 +569,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -525,7 +650,9 @@ "display_name": "Agent", "id": "Agent-LDhCf", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -574,7 +701,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -603,7 +732,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -652,7 +783,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -703,7 +836,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -777,7 +912,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -871,7 +1008,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -905,7 +1045,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -921,7 +1065,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -941,7 +1087,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -961,7 +1109,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -998,7 +1148,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1019,7 +1171,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -1074,7 +1228,9 @@ "data": { "id": "CalculatorComponent-unDLj", "node": { - "base_classes": ["Data"], + "base_classes": [ + "Data" + ], "beta": false, "category": "tools", "conditional_paths": [], @@ -1083,7 +1239,9 @@ "display_name": "Calculator", "documentation": "", "edited": false, - "field_order": ["expression"], + "field_order": [ + "expression" + ], "frozen": false, "icon": "calculator", "key": "CalculatorComponent", @@ -1093,15 +1251,17 @@ "output_types": [], "outputs": [ { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", "cache": true, - "required_inputs": null + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -1132,7 +1292,9 @@ "display_name": "Expression", "dynamic": false, "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "list_add_label": "Add More", "load_from_db": false, @@ -1148,84 +1310,89 @@ "value": "" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, "table_icon": "Hammer", "table_options": { "block_add": true, "block_delete": true, "block_edit": true, - "block_sort": true, "block_filter": true, "block_hide": true, "block_select": true, - "hide_options": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." + "hide_options": true }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", "name": "None-evaluate_expression", - "tags": ["None-evaluate_expression"] + "tags": [ + "None-evaluate_expression" + ] } - ], - "display_name": "Edit tools", - "advanced": false, - "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" + ] } }, "tool_mode": true @@ -1247,75 +1414,6 @@ "type": "genericNode" } ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-LDhCf", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-YQ7Vi", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-LDhCf{œdataTypeœ:œAgentœ,œidœ:œAgent-LDhCfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-YQ7Vi{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-YQ7Viœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-LDhCf", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-LDhCfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-YQ7Vi", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-YQ7Viœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-Pe4nO", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-LDhCf", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-Pe4nO{œdataTypeœ:œPromptœ,œidœ:œPrompt-Pe4nOœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-LDhCf{œfieldNameœ:œinput_valueœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-Pe4nO", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-Pe4nOœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-LDhCf", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "source": "CalculatorComponent-unDLj", - "sourceHandle": "{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-unDLjœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-LDhCf", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-LDhCf", - "inputTypes": ["Tool"], - "type": "other" - }, - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-unDLj", - "name": "component_as_tool", - "output_types": ["Tool"] - } - }, - "id": "xy-edge__CalculatorComponent-unDLj{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-unDLjœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-LDhCf{œfieldNameœ:œtoolsœ,œidœ:œAgent-LDhCfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - } - ], "viewport": { "x": -412.6248764419154, "y": 239.5139629945674, @@ -1330,5 +1428,8 @@ "is_component": false, "last_tested_version": "1.1.1", "name": "SaaS Pricing", - "tags": ["agents", "assistants"] -} + "tags": [ + "agents", + "assistants" + ] +} \ No newline at end of file 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 c7a7efbbe..b968e1050 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 @@ -1,5 +1,302 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-cisfj", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_prompt", + "id": "Agent-b9Ndr", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-cisfj{œdataTypeœ:œPromptœ,œidœ:œPrompt-cisfjœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-b9Ndr{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-cisfj", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-cisfjœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-b9Ndr", + "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-b9Ndrœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-uNyIS", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_prompt", + "id": "Agent-opLbj", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-uNyIS{œdataTypeœ:œPromptœ,œidœ:œPrompt-uNyISœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-opLbj{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-uNyIS", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-uNyISœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-opLbj", + "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-opLbjœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-b9Ndr", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-E20qD", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-b9Ndr{œdataTypeœ:œAgentœ,œidœ:œAgent-b9Ndrœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-E20qD{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-E20qDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-b9Ndr", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-b9Ndrœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-E20qD", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-E20qDœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-opLbj", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "finance_agent_output", + "id": "Prompt-cisfj", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-opLbj{œdataTypeœ:œAgentœ,œidœ:œAgent-opLbjœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-cisfj{œfieldNameœ:œfinance_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "Agent-opLbj", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-opLbjœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-cisfj", + "targetHandle": "{œfieldNameœ: œfinance_agent_outputœ, œidœ: œPrompt-cisfjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-hE8ZA", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-AngMf", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-hE8ZA{œdataTypeœ:œChatInputœ,œidœ:œChatInput-hE8ZAœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-AngMf{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-hE8ZA", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-hE8ZAœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-AngMf", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-AngMfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-IG0jU", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "system_prompt", + "id": "Agent-AngMf", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-IG0jU{œdataTypeœ:œPromptœ,œidœ:œPrompt-IG0jUœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-AngMf{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-IG0jU", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-IG0jUœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-AngMf", + "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-AngMfœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "TavilyAISearch", + "id": "TavilyAISearch-KZP5i", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-AngMf", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-TavilyAISearch-KZP5i{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-KZP5iœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-AngMf{œfieldNameœ:œtoolsœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "TavilyAISearch-KZP5i", + "sourceHandle": "{œdataTypeœ: œTavilyAISearchœ, œidœ: œTavilyAISearch-KZP5iœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-AngMf", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-AngMfœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-AngMf", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-opLbj", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-AngMf{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-opLbj{œfieldNameœ:œinput_valueœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-AngMf", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-AngMfœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-opLbj", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-opLbjœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-AngMf", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "research_agent_output", + "id": "Prompt-cisfj", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-AngMf{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-cisfj{œfieldNameœ:œresearch_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "Agent-AngMf", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-AngMfœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-cisfj", + "targetHandle": "{œfieldNameœ: œresearch_agent_outputœ, œidœ: œPrompt-cisfjœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "CalculatorComponent", + "id": "CalculatorComponent-ZUJg0", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-b9Ndr", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__CalculatorComponent-ZUJg0{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-ZUJg0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-b9Ndr{œfieldNameœ:œtoolsœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "CalculatorComponent-ZUJg0", + "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-ZUJg0œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-b9Ndr", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-b9Ndrœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "YfinanceComponent", + "id": "YfinanceComponent-gHp4w", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-opLbj", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__YfinanceComponent-gHp4w{œdataTypeœ:œYfinanceComponentœ,œidœ:œYfinanceComponent-gHp4wœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-opLbj{œfieldNameœ:œtoolsœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "YfinanceComponent-gHp4w", + "sourceHandle": "{œdataTypeœ: œYfinanceComponentœ, œidœ: œYfinanceComponent-gHp4wœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-opLbj", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-opLbjœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { @@ -7,7 +304,9 @@ "display_name": "Chat Output", "id": "ChatOutput-E20qD", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -39,7 +338,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -52,7 +353,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -72,7 +375,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -110,7 +415,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -130,7 +437,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -151,7 +460,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -167,7 +479,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -187,7 +501,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -223,7 +539,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -245,6 +563,10 @@ "dragging": false, "height": 234, "id": "ChatOutput-E20qD", + "measured": { + "height": 234, + "width": 320 + }, "position": { "x": 1239.222567317785, "y": -920.0283175735606 @@ -255,11 +577,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 234 - } + "width": 320 }, { "data": { @@ -267,7 +585,9 @@ "display_name": "Finance Agent", "id": "Agent-opLbj", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -316,7 +636,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -345,7 +667,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -394,7 +718,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -445,7 +771,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -519,7 +847,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -613,7 +943,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -647,7 +980,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -663,7 +1000,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -683,7 +1022,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -703,7 +1044,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -740,7 +1083,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -761,7 +1106,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -796,6 +1143,10 @@ "dragging": false, "height": 650, "id": "Agent-opLbj", + "measured": { + "height": 650, + "width": 320 + }, "position": { "x": 45.70736046026991, "y": -1369.035463408626 @@ -806,11 +1157,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 650 - } + "width": 320 }, { "data": { @@ -818,7 +1165,9 @@ "display_name": "Analysis & Editor Agent", "id": "Agent-b9Ndr", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -867,7 +1216,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -896,7 +1247,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -945,7 +1298,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -996,7 +1351,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1070,7 +1427,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -1164,7 +1523,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -1198,7 +1560,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -1214,7 +1580,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1234,7 +1602,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1254,7 +1624,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1291,7 +1663,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1312,7 +1686,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -1347,6 +1723,10 @@ "dragging": false, "height": 650, "id": "Agent-b9Ndr", + "measured": { + "height": 650, + "width": 320 + }, "position": { "x": 815.1900903820148, "y": -1365.4053932711827 @@ -1357,11 +1737,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 650 - } + "width": 320 }, { "data": { @@ -1369,7 +1745,9 @@ "display_name": "Prompt", "id": "Prompt-IG0jU", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { @@ -1380,7 +1758,9 @@ "documentation": "", "edited": false, "error": null, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": true, "full_path": null, "icon": "prompts", @@ -1399,7 +1779,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1448,7 +1830,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -1470,6 +1854,10 @@ "dragging": false, "height": 260, "id": "Prompt-IG0jU", + "measured": { + "height": 260, + "width": 320 + }, "position": { "x": -1142.2312935529987, "y": -1107.442614776065 @@ -1480,11 +1868,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 260 - } + "width": 320 }, { "data": { @@ -1492,7 +1876,9 @@ "display_name": "Prompt", "id": "Prompt-uNyIS", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { @@ -1503,7 +1889,9 @@ "documentation": "", "edited": false, "error": null, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "full_path": null, "icon": "prompts", @@ -1522,7 +1910,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1571,7 +1961,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -1593,6 +1985,10 @@ "dragging": false, "height": 260, "id": "Prompt-uNyIS", + "measured": { + "height": 260, + "width": 320 + }, "position": { "x": -344.9674638932195, "y": -1280.1782190739505 @@ -1603,11 +1999,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 260 - } + "width": 320 }, { "data": { @@ -1615,18 +2007,25 @@ "display_name": "Prompt", "id": "Prompt-cisfj", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": { - "template": ["research_agent_output", "finance_agent_output"] + "template": [ + "research_agent_output", + "finance_agent_output" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", "documentation": "", "edited": false, "error": null, - "field_order": ["template"], + "field_order": [ + "template" + ], "frozen": false, "full_path": null, "icon": "prompts", @@ -1645,7 +2044,9 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1678,7 +2079,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1698,7 +2102,10 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Message", "Text"], + "input_types": [ + "Message", + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1734,7 +2141,9 @@ "display_name": "Tool Placeholder", "dynamic": false, "info": "A placeholder input for tool mode.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "tool_placeholder", @@ -1756,6 +2165,10 @@ "dragging": false, "height": 433, "id": "Prompt-cisfj", + "measured": { + "height": 433, + "width": 320 + }, "position": { "x": 416.02309796632085, "y": -1081.5957453651372 @@ -1766,17 +2179,15 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 433 - } + "width": 320 }, { "data": { "id": "ChatInput-hE8ZA", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1808,7 +2219,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1821,7 +2234,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -1841,7 +2256,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -1944,7 +2361,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -1960,7 +2380,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1980,7 +2402,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -2016,7 +2440,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -2038,6 +2464,10 @@ "dragging": false, "height": 234, "id": "ChatInput-hE8ZA", + "measured": { + "height": 234, + "width": 320 + }, "position": { "x": -1510.6054210793818, "y": -947.702056394023 @@ -2048,11 +2478,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 234 - } + "width": 320 }, { "data": { @@ -2060,190 +2486,17 @@ "display_name": "Tavily AI Search [DEPRECATED]", "id": "TavilyAISearch-KZP5i", "node": { - "template": { - "_type": "Component", - "api_key": { - "load_from_db": false, - "required": true, - "placeholder": "", - "show": true, - "name": "api_key", - "value": "", - "display_name": "Tavily API Key", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "Your Tavily API Key.", - "title_case": false, - "password": true, - "type": "str", - "_input_type": "SecretStrInput" - }, - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from enum import Enum\n\nimport httpx\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass TavilySearchDepth(Enum):\n BASIC = \"basic\"\n ADVANCED = \"advanced\"\n\n\nclass TavilySearchTopic(Enum):\n GENERAL = \"general\"\n NEWS = \"news\"\n\n\nclass TavilySearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query you want to execute with Tavily.\")\n search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description=\"The depth of the search.\")\n topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description=\"The category of the search.\")\n max_results: int = Field(5, description=\"The maximum number of search results to return.\")\n include_images: bool = Field(default=False, description=\"Include a list of query-related images in the response.\")\n include_answer: bool = Field(default=False, description=\"Include a short answer to original query.\")\n\n\nclass TavilySearchToolComponent(LCToolComponent):\n display_name = \"Tavily AI Search [DEPRECATED]\"\n description = \"\"\"**Tavily AI** is a search engine optimized for LLMs and RAG, \\\n aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n\"\"\"\n icon = \"TavilyIcon\"\n name = \"TavilyAISearch\"\n documentation = \"https://docs.tavily.com/\"\n legacy = True\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Tavily API Key\",\n required=True,\n info=\"Your Tavily API Key.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The search query you want to execute with Tavily.\",\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=list(TavilySearchDepth),\n value=TavilySearchDepth.ADVANCED,\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=list(TavilySearchTopic),\n value=TavilySearchTopic.GENERAL,\n advanced=True,\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"The maximum number of search results to return.\",\n value=5,\n advanced=True,\n ),\n BoolInput(\n name=\"include_images\",\n display_name=\"Include Images\",\n info=\"Include a list of query-related images in the response.\",\n value=True,\n advanced=True,\n ),\n BoolInput(\n name=\"include_answer\",\n display_name=\"Include Answer\",\n info=\"Include a short answer to original query.\",\n value=True,\n advanced=True,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n # Convert string values to enum instances with validation\n try:\n search_depth_enum = (\n self.search_depth\n if isinstance(self.search_depth, TavilySearchDepth)\n else TavilySearchDepth(str(self.search_depth).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid search depth value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n try:\n topic_enum = (\n self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid topic value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n return self._tavily_search(\n self.query,\n search_depth=search_depth_enum,\n topic=topic_enum,\n max_results=self.max_results,\n include_images=self.include_images,\n include_answer=self.include_answer,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"tavily_search\",\n description=\"Perform a web search using the Tavily API.\",\n func=self._tavily_search,\n args_schema=TavilySearchSchema,\n )\n\n def _tavily_search(\n self,\n query: str,\n *,\n search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,\n topic: TavilySearchTopic = TavilySearchTopic.GENERAL,\n max_results: int = 5,\n include_images: bool = False,\n include_answer: bool = False,\n ) -> list[Data]:\n # Validate enum values\n if not isinstance(search_depth, TavilySearchDepth):\n msg = f\"Invalid search_depth value: {search_depth}\"\n raise TypeError(msg)\n if not isinstance(topic, TavilySearchTopic):\n msg = f\"Invalid topic value: {topic}\"\n raise TypeError(msg)\n\n try:\n url = \"https://api.tavily.com/search\"\n headers = {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json\",\n }\n payload = {\n \"api_key\": self.api_key,\n \"query\": query,\n \"search_depth\": search_depth.value,\n \"topic\": topic.value,\n \"max_results\": max_results,\n \"include_images\": include_images,\n \"include_answer\": include_answer,\n }\n\n with httpx.Client() as client:\n response = client.post(url, json=payload, headers=headers)\n\n response.raise_for_status()\n search_results = response.json()\n\n data_results = [\n Data(\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": result.get(\"content\"),\n \"score\": result.get(\"score\"),\n }\n )\n for result in search_results.get(\"results\", [])\n ]\n\n if include_answer and search_results.get(\"answer\"):\n data_results.insert(0, Data(data={\"answer\": search_results[\"answer\"]}))\n\n if include_images and search_results.get(\"images\"):\n data_results.append(Data(data={\"images\": search_results[\"images\"]}))\n\n self.status = data_results # type: ignore[assignment]\n\n except httpx.HTTPStatusError as e:\n error_message = f\"HTTP error: {e.response.status_code} - {e.response.text}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.opt(exception=True).debug(\"Error running Tavily Search\")\n self.status = error_message\n raise ToolException(error_message) from e\n return data_results\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "include_answer": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "include_answer", - "value": true, - "display_name": "Include Answer", - "advanced": true, - "dynamic": false, - "info": "Include a short answer to original query.", - "title_case": false, - "type": "bool", - "_input_type": "BoolInput" - }, - "include_images": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "include_images", - "value": true, - "display_name": "Include Images", - "advanced": true, - "dynamic": false, - "info": "Include a list of query-related images in the response.", - "title_case": false, - "type": "bool", - "_input_type": "BoolInput" - }, - "max_results": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "max_results", - "value": 5, - "display_name": "Max Results", - "advanced": true, - "dynamic": false, - "info": "The maximum number of search results to return.", - "title_case": false, - "type": "int", - "_input_type": "IntInput" - }, - "query": { - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "query", - "value": "", - "display_name": "Search Query", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "The search query you want to execute with Tavily.", - "title_case": false, - "type": "str", - "_input_type": "MessageTextInput" - }, - "search_depth": { - "tool_mode": false, - "trace_as_metadata": true, - "options": ["basic", "advanced"], - "combobox": false, - "required": false, - "placeholder": "", - "show": true, - "name": "search_depth", - "value": "advanced", - "display_name": "Search Depth", - "advanced": true, - "dynamic": false, - "info": "The depth of the search.", - "title_case": false, - "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false - }, - "topic": { - "tool_mode": false, - "trace_as_metadata": true, - "options": ["general", "news"], - "combobox": false, - "required": false, - "placeholder": "", - "show": true, - "name": "topic", - "value": "general", - "display_name": "Search Topic", - "advanced": true, - "dynamic": false, - "info": "The category of the search.", - "title_case": false, - "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false - } - }, + "base_classes": [ + "Data", + "Tool" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n", - "icon": "TavilyIcon", - "base_classes": ["Data", "Tool"], "display_name": "Tavily AI Search [DEPRECATED]", "documentation": "https://docs.tavily.com/", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Data"], - "selected": "Data", - "name": "api_run_model", - "display_name": "Data", - "method": "run_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - }, - { - "types": ["Tool"], - "selected": "Tool", - "name": "api_build_tool", - "display_name": "Tool", - "method": "build_tool", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - } - ], + "edited": false, "field_order": [ "api_key", "query", @@ -2253,10 +2506,204 @@ "include_images", "include_answer" ], - "beta": false, + "frozen": false, + "icon": "TavilyIcon", "legacy": true, - "edited": false, "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "method": "run_model", + "name": "api_run_model", + "required_inputs": [ + "api_key" + ], + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Tool", + "method": "build_tool", + "name": "api_build_tool", + "required_inputs": [ + "api_key" + ], + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "api_key": { + "_input_type": "SecretStrInput", + "advanced": false, + "display_name": "Tavily API Key", + "dynamic": false, + "info": "Your Tavily API Key.", + "input_types": [ + "Message" + ], + "load_from_db": false, + "name": "api_key", + "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from enum import Enum\n\nimport httpx\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass TavilySearchDepth(Enum):\n BASIC = \"basic\"\n ADVANCED = \"advanced\"\n\n\nclass TavilySearchTopic(Enum):\n GENERAL = \"general\"\n NEWS = \"news\"\n\n\nclass TavilySearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query you want to execute with Tavily.\")\n search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description=\"The depth of the search.\")\n topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description=\"The category of the search.\")\n max_results: int = Field(5, description=\"The maximum number of search results to return.\")\n include_images: bool = Field(default=False, description=\"Include a list of query-related images in the response.\")\n include_answer: bool = Field(default=False, description=\"Include a short answer to original query.\")\n\n\nclass TavilySearchToolComponent(LCToolComponent):\n display_name = \"Tavily AI Search [DEPRECATED]\"\n description = \"\"\"**Tavily AI** is a search engine optimized for LLMs and RAG, \\\n aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n\"\"\"\n icon = \"TavilyIcon\"\n name = \"TavilyAISearch\"\n documentation = \"https://docs.tavily.com/\"\n legacy = True\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Tavily API Key\",\n required=True,\n info=\"Your Tavily API Key.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The search query you want to execute with Tavily.\",\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=list(TavilySearchDepth),\n value=TavilySearchDepth.ADVANCED,\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=list(TavilySearchTopic),\n value=TavilySearchTopic.GENERAL,\n advanced=True,\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"The maximum number of search results to return.\",\n value=5,\n advanced=True,\n ),\n BoolInput(\n name=\"include_images\",\n display_name=\"Include Images\",\n info=\"Include a list of query-related images in the response.\",\n value=True,\n advanced=True,\n ),\n BoolInput(\n name=\"include_answer\",\n display_name=\"Include Answer\",\n info=\"Include a short answer to original query.\",\n value=True,\n advanced=True,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n # Convert string values to enum instances with validation\n try:\n search_depth_enum = (\n self.search_depth\n if isinstance(self.search_depth, TavilySearchDepth)\n else TavilySearchDepth(str(self.search_depth).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid search depth value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n try:\n topic_enum = (\n self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid topic value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n return self._tavily_search(\n self.query,\n search_depth=search_depth_enum,\n topic=topic_enum,\n max_results=self.max_results,\n include_images=self.include_images,\n include_answer=self.include_answer,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"tavily_search\",\n description=\"Perform a web search using the Tavily API.\",\n func=self._tavily_search,\n args_schema=TavilySearchSchema,\n )\n\n def _tavily_search(\n self,\n query: str,\n *,\n search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,\n topic: TavilySearchTopic = TavilySearchTopic.GENERAL,\n max_results: int = 5,\n include_images: bool = False,\n include_answer: bool = False,\n ) -> list[Data]:\n # Validate enum values\n if not isinstance(search_depth, TavilySearchDepth):\n msg = f\"Invalid search_depth value: {search_depth}\"\n raise TypeError(msg)\n if not isinstance(topic, TavilySearchTopic):\n msg = f\"Invalid topic value: {topic}\"\n raise TypeError(msg)\n\n try:\n url = \"https://api.tavily.com/search\"\n headers = {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json\",\n }\n payload = {\n \"api_key\": self.api_key,\n \"query\": query,\n \"search_depth\": search_depth.value,\n \"topic\": topic.value,\n \"max_results\": max_results,\n \"include_images\": include_images,\n \"include_answer\": include_answer,\n }\n\n with httpx.Client() as client:\n response = client.post(url, json=payload, headers=headers)\n\n response.raise_for_status()\n search_results = response.json()\n\n data_results = [\n Data(\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": result.get(\"content\"),\n \"score\": result.get(\"score\"),\n }\n )\n for result in search_results.get(\"results\", [])\n ]\n\n if include_answer and search_results.get(\"answer\"):\n data_results.insert(0, Data(data={\"answer\": search_results[\"answer\"]}))\n\n if include_images and search_results.get(\"images\"):\n data_results.append(Data(data={\"images\": search_results[\"images\"]}))\n\n self.status = data_results # type: ignore[assignment]\n\n except httpx.HTTPStatusError as e:\n error_message = f\"HTTP error: {e.response.status_code} - {e.response.text}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.opt(exception=True).debug(\"Error running Tavily Search\")\n self.status = error_message\n raise ToolException(error_message) from e\n return data_results\n" + }, + "include_answer": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Answer", + "dynamic": false, + "info": "Include a short answer to original query.", + "list": false, + "list_add_label": "Add More", + "name": "include_answer", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "include_images": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Images", + "dynamic": false, + "info": "Include a list of query-related images in the response.", + "list": false, + "list_add_label": "Add More", + "name": "include_images", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": true + }, + "max_results": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Results", + "dynamic": false, + "info": "The maximum number of search results to return.", + "list": false, + "list_add_label": "Add More", + "name": "max_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 5 + }, + "query": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Search Query", + "dynamic": false, + "info": "The search query you want to execute with Tavily.", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "query", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "search_depth": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "display_name": "Search Depth", + "dynamic": false, + "info": "The depth of the search.", + "load_from_db": false, + "name": "search_depth", + "options": [ + "basic", + "advanced" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "advanced" + }, + "topic": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "display_name": "Search Topic", + "dynamic": false, + "info": "The category of the search.", + "load_from_db": false, + "name": "topic", + "options": [ + "general", + "news" + ], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "general" + } + }, "tool_mode": false }, "type": "TavilyAISearch" @@ -2264,6 +2711,10 @@ "dragging": false, "height": 394, "id": "TavilyAISearch-KZP5i", + "measured": { + "height": 394, + "width": 320 + }, "position": { "x": -1132.8634419233736, "y": -770.0391255413992 @@ -2274,11 +2725,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 394 - } + "width": 320 }, { "data": { @@ -2294,6 +2741,10 @@ "dragging": false, "height": 800, "id": "note-e59F1", + "measured": { + "height": 800, + "width": 325 + }, "position": { "x": -2122.739127560837, "y": -1302.6582482086806 @@ -2309,11 +2760,7 @@ "width": 600 }, "type": "noteNode", - "width": 600, - "measured": { - "width": 325, - "height": 800 - } + "width": 600 }, { "data": { @@ -2331,6 +2778,10 @@ "dragging": false, "height": 800, "id": "note-7HeUD", + "measured": { + "height": 800, + "width": 325 + }, "position": { "x": -1456.0688717707517, "y": -1916.6876704866322 @@ -2346,11 +2797,7 @@ "width": 600 }, "type": "noteNode", - "width": 600, - "measured": { - "width": 325, - "height": 800 - } + "width": 600 }, { "data": { @@ -2358,7 +2805,9 @@ "display_name": "Researcher Agent", "id": "Agent-AngMf", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2407,7 +2856,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -2436,7 +2887,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2485,7 +2938,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": true, "name": "api_key", "password": true, @@ -2536,7 +2991,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -2610,7 +3067,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -2704,7 +3163,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -2738,7 +3200,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -2754,7 +3220,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -2774,7 +3242,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -2794,7 +3264,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2831,7 +3303,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2852,7 +3326,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -2887,6 +3363,10 @@ "dragging": false, "height": 650, "id": "Agent-AngMf", + "measured": { + "height": 650, + "width": 320 + }, "position": { "x": -715.1798010873374, "y": -1342.256094001045 @@ -2897,11 +3377,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 320, - "height": 650 - } + "width": 320 }, { "data": { @@ -2919,6 +3395,10 @@ "dragging": false, "height": 324, "id": "note-RNWTM", + "measured": { + "height": 324, + "width": 325 + }, "position": { "x": -1144.3898055225054, "y": -844.3506743985376 @@ -2934,11 +3414,7 @@ "width": 347 }, "type": "noteNode", - "width": 347, - "measured": { - "width": 325, - "height": 324 - } + "width": 347 }, { "data": { @@ -2956,6 +3432,10 @@ "dragging": false, "height": 324, "id": "note-Rv3Gc", + "measured": { + "height": 324, + "width": 325 + }, "position": { "x": -739.4383746675942, "y": -1672.0874594411662 @@ -2971,44 +3451,81 @@ "width": 370 }, "type": "noteNode", - "width": 370, - "measured": { - "width": 325, - "height": 324 - } + "width": 370 }, { - "id": "YfinanceComponent-gHp4w", - "type": "genericNode", - "position": { - "x": -347.05382068428014, - "y": -950.8279673971418 - }, "data": { + "id": "YfinanceComponent-gHp4w", "node": { + "base_classes": [ + "Data", + "Message" + ], + "beta": false, + "category": "tools", + "conditional_paths": [], + "custom_fields": {}, + "description": "Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", + "display_name": "Yahoo Finance", + "documentation": "", + "edited": false, + "field_order": [ + "symbol", + "method", + "num_news" + ], + "frozen": false, + "icon": "trending-up", + "key": "YfinanceComponent", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "score": 0.007568328950209746, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.custom import Component\nfrom langflow.inputs import DropdownInput, IntInput, MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceComponent(Component):\n display_name = \"Yahoo Finance\"\n description = \"\"\"Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \\\nto access financial data and market information from Yahoo Finance.\"\"\"\n icon = \"trending-up\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n tool_mode=True,\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Text\", name=\"text\", method=\"fetch_content_text\"),\n ]\n\n def run_model(self) -> list[Data]:\n return self.fetch_content()\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n result_string = \"\"\n for item in data:\n result_string += item.text + \"\\n\"\n self.status = result_string\n return Message(text=result_string)\n\n def _fetch_yfinance_data(self, ticker: yf.Ticker, method: YahooFinanceMethod, num_news: int | None) -> str:\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n return pprint.pformat(result)\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def fetch_content(self) -> list[Data]:\n try:\n return self._yahoo_finance_tool(\n self.symbol,\n YahooFinanceMethod(self.method),\n self.num_news,\n )\n except ToolException:\n raise\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n result = self._fetch_yfinance_data(ticker, method, num_news)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [\n Data(text=f\"{article['title']}: {article['link']}\", data=article)\n for article in ast.literal_eval(result)\n ]\n else:\n data_list = [Data(text=result, data={\"result\": result})]\n\n return data_list\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import ast\nimport pprint\nfrom enum import Enum\n\nimport yfinance as yf\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.custom import Component\nfrom langflow.inputs import DropdownInput, IntInput, MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass YahooFinanceMethod(Enum):\n GET_INFO = \"get_info\"\n GET_NEWS = \"get_news\"\n GET_ACTIONS = \"get_actions\"\n GET_ANALYSIS = \"get_analysis\"\n GET_BALANCE_SHEET = \"get_balance_sheet\"\n GET_CALENDAR = \"get_calendar\"\n GET_CASHFLOW = \"get_cashflow\"\n GET_INSTITUTIONAL_HOLDERS = \"get_institutional_holders\"\n GET_RECOMMENDATIONS = \"get_recommendations\"\n GET_SUSTAINABILITY = \"get_sustainability\"\n GET_MAJOR_HOLDERS = \"get_major_holders\"\n GET_MUTUALFUND_HOLDERS = \"get_mutualfund_holders\"\n GET_INSIDER_PURCHASES = \"get_insider_purchases\"\n GET_INSIDER_TRANSACTIONS = \"get_insider_transactions\"\n GET_INSIDER_ROSTER_HOLDERS = \"get_insider_roster_holders\"\n GET_DIVIDENDS = \"get_dividends\"\n GET_CAPITAL_GAINS = \"get_capital_gains\"\n GET_SPLITS = \"get_splits\"\n GET_SHARES = \"get_shares\"\n GET_FAST_INFO = \"get_fast_info\"\n GET_SEC_FILINGS = \"get_sec_filings\"\n GET_RECOMMENDATIONS_SUMMARY = \"get_recommendations_summary\"\n GET_UPGRADES_DOWNGRADES = \"get_upgrades_downgrades\"\n GET_EARNINGS = \"get_earnings\"\n GET_INCOME_STMT = \"get_income_stmt\"\n\n\nclass YahooFinanceSchema(BaseModel):\n symbol: str = Field(..., description=\"The stock symbol to retrieve data for.\")\n method: YahooFinanceMethod = Field(YahooFinanceMethod.GET_INFO, description=\"The type of data to retrieve.\")\n num_news: int | None = Field(5, description=\"The number of news articles to retrieve.\")\n\n\nclass YfinanceComponent(Component):\n display_name = \"Yahoo Finance\"\n description = \"\"\"Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) \\\nto access financial data and market information from Yahoo Finance.\"\"\"\n icon = \"trending-up\"\n\n inputs = [\n MessageTextInput(\n name=\"symbol\",\n display_name=\"Stock Symbol\",\n info=\"The stock symbol to retrieve data for (e.g., AAPL, GOOG).\",\n tool_mode=True,\n ),\n DropdownInput(\n name=\"method\",\n display_name=\"Data Method\",\n info=\"The type of data to retrieve.\",\n options=list(YahooFinanceMethod),\n value=\"get_news\",\n ),\n IntInput(\n name=\"num_news\",\n display_name=\"Number of News\",\n info=\"The number of news articles to retrieve (only applicable for get_news).\",\n value=5,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Text\", name=\"text\", method=\"fetch_content_text\"),\n ]\n\n def run_model(self) -> list[Data]:\n return self.fetch_content()\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n result_string = \"\"\n for item in data:\n result_string += item.text + \"\\n\"\n self.status = result_string\n return Message(text=result_string)\n\n def _fetch_yfinance_data(self, ticker: yf.Ticker, method: YahooFinanceMethod, num_news: int | None) -> str:\n try:\n if method == YahooFinanceMethod.GET_INFO:\n result = ticker.info\n elif method == YahooFinanceMethod.GET_NEWS:\n result = ticker.news[:num_news]\n else:\n result = getattr(ticker, method.value)()\n return pprint.pformat(result)\n except Exception as e:\n error_message = f\"Error retrieving data: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def fetch_content(self) -> list[Data]:\n try:\n return self._yahoo_finance_tool(\n self.symbol,\n YahooFinanceMethod(self.method),\n self.num_news,\n )\n except ToolException:\n raise\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n\n def _yahoo_finance_tool(\n self,\n symbol: str,\n method: YahooFinanceMethod,\n num_news: int | None = 5,\n ) -> list[Data]:\n ticker = yf.Ticker(symbol)\n result = self._fetch_yfinance_data(ticker, method, num_news)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [\n Data(text=f\"{article['title']}: {article['link']}\", data=article)\n for article in ast.literal_eval(result)\n ]\n else:\n data_list = [Data(text=result, data={\"result\": result})]\n\n return data_list\n" }, "method": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "DropdownInput", + "advanced": false, + "combobox": false, + "display_name": "Data Method", + "dynamic": false, + "info": "The type of data to retrieve.", + "name": "method", "options": [ "get_info", "get_news", @@ -3036,616 +3553,355 @@ "get_earnings", "get_income_stmt" ], - "combobox": false, - "required": false, "placeholder": "", + "required": false, "show": true, - "name": "method", - "value": "get_news", - "display_name": "Data Method", - "advanced": false, - "dynamic": false, - "info": "The type of data to retrieve.", "title_case": false, - "type": "str", - "_input_type": "DropdownInput" - }, - "num_news": { "tool_mode": false, "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "num_news", - "value": 5, - "display_name": "Number of News", + "type": "str", + "value": "get_news" + }, + "num_news": { + "_input_type": "IntInput", "advanced": false, + "display_name": "Number of News", "dynamic": false, "info": "The number of news articles to retrieve (only applicable for get_news).", + "list": false, + "list_add_label": "Add More", + "name": "num_news", + "placeholder": "", + "required": false, + "show": true, "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, "type": "int", - "_input_type": "IntInput" + "value": 5 }, "symbol": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Stock Symbol", + "dynamic": false, + "info": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "symbol", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, "tool_mode": true, "trace_as_input": true, "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "symbol", - "value": "", - "display_name": "Stock Symbol", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "The stock symbol to retrieve data for (e.g., AAPL, GOOG).", - "title_case": false, "type": "str", - "_input_type": "MessageTextInput" + "value": "" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, "table_icon": "Hammer", "table_options": { "block_add": true, "block_delete": true, "block_edit": true, - "block_sort": true, "block_filter": true, "block_hide": true, "block_select": true, - "hide_options": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." + "hide_options": true }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "YfinanceComponent-fetch_content", "description": "fetch_content() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "tags": ["YfinanceComponent-fetch_content"] + "name": "YfinanceComponent-fetch_content", + "tags": [ + "YfinanceComponent-fetch_content" + ] }, { - "name": "YfinanceComponent-fetch_content_text", "description": "fetch_content_text() - Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "tags": ["YfinanceComponent-fetch_content_text"] + "name": "YfinanceComponent-fetch_content_text", + "tags": [ + "YfinanceComponent-fetch_content_text" + ] } - ], - "display_name": "Edit tools", - "advanced": false, - "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" + ] } }, - "description": "Uses [yfinance](https://pypi.org/project/yfinance/) (unofficial package) to access financial data and market information from Yahoo Finance.", - "icon": "trending-up", - "base_classes": ["Data", "Message"], - "display_name": "Yahoo Finance", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": null - } - ], - "field_order": ["symbol", "method", "num_news"], - "beta": false, - "legacy": false, - "edited": false, - "metadata": {}, - "tool_mode": true, - "category": "tools", - "key": "YfinanceComponent", - "score": 0.007568328950209746 + "tool_mode": true }, "showNode": true, - "type": "YfinanceComponent", - "id": "YfinanceComponent-gHp4w" + "type": "YfinanceComponent" + }, + "dragging": true, + "id": "YfinanceComponent-gHp4w", + "measured": { + "height": 517, + "width": 320 + }, + "position": { + "x": -347.05382068428014, + "y": -950.8279673971418 }, "selected": true, - "measured": { - "width": 320, - "height": 517 - }, - "dragging": true + "type": "genericNode" }, { + "data": { + "id": "CalculatorComponent-ZUJg0", + "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "category": "tools", + "conditional_paths": [], + "custom_fields": {}, + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator", + "documentation": "", + "edited": false, + "field_order": [ + "expression" + ], + "frozen": false, + "icon": "calculator", + "key": "CalculatorComponent", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "score": 0.001, + "template": { + "_type": "Component", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom langflow.custom import Component\nfrom langflow.inputs import MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n if isinstance(node, ast.Num): # For backwards compatibility\n if isinstance(node.n, int | float):\n return float(node.n)\n error_msg = f\"Unsupported number type: {type(node.n).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n" + }, + "expression": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Expression", + "dynamic": false, + "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "expression", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" + }, + "tools_metadata": { + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", + "is_list": true, + "list_add_label": "Add More", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "table_icon": "Hammer", + "table_options": { + "block_add": true, + "block_delete": true, + "block_edit": true, + "block_filter": true, + "block_hide": true, + "block_select": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "field_parsers": { + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] + }, + "hide_options": true + }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", + "value": [ + { + "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", + "name": "CalculatorComponent-evaluate_expression", + "tags": [ + "CalculatorComponent-evaluate_expression" + ] + } + ] + } + }, + "tool_mode": true + }, + "showNode": true, + "type": "CalculatorComponent" + }, + "dragging": false, "id": "CalculatorComponent-ZUJg0", - "type": "genericNode", + "measured": { + "height": 333, + "width": 320 + }, "position": { "x": 418.5430081507146, "y": -618.940894040711 }, - "data": { - "node": { - "template": { - "_type": "Component", - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom langflow.custom import Component\nfrom langflow.inputs import MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n if isinstance(node, ast.Num): # For backwards compatibility\n if isinstance(node.n, int | float):\n return float(node.n)\n error_msg = f\"Unsupported number type: {type(node.n).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "expression": { - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "expression", - "value": "", - "display_name": "Expression", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", - "title_case": false, - "type": "str", - "_input_type": "MessageTextInput" - }, - "tools_metadata": { - "tool_mode": false, - "is_list": true, - "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", - "table_icon": "Hammer", - "table_options": { - "block_add": true, - "block_delete": true, - "block_edit": true, - "block_sort": true, - "block_filter": true, - "block_hide": true, - "block_select": true, - "hide_options": true, - "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" - }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." - }, - "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", - "value": [ - { - "name": "CalculatorComponent-evaluate_expression", - "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", - "tags": ["CalculatorComponent-evaluate_expression"] - } - ], - "display_name": "Edit tools", - "advanced": false, - "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" - } - }, - "description": "Perform basic arithmetic operations on a given expression.", - "icon": "calculator", - "base_classes": ["Data"], - "display_name": "Calculator", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": null - } - ], - "field_order": ["expression"], - "beta": false, - "legacy": false, - "edited": false, - "metadata": {}, - "tool_mode": true, - "category": "tools", - "key": "CalculatorComponent", - "score": 0.001 - }, - "showNode": true, - "type": "CalculatorComponent", - "id": "CalculatorComponent-ZUJg0" - }, "selected": false, - "measured": { - "width": 320, - "height": 333 - }, - "dragging": false - } - ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-cisfj", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-b9Ndr", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-cisfj{œdataTypeœ:œPromptœ,œidœ:œPrompt-cisfjœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-b9Ndr{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-cisfj", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-cisfjœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-b9Ndr", - "targetHandle": "{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-uNyIS", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-opLbj", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-uNyIS{œdataTypeœ:œPromptœ,œidœ:œPrompt-uNyISœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-opLbj{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-uNyIS", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-uNyISœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-opLbj", - "targetHandle": "{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-b9Ndr", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-E20qD", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-b9Ndr{œdataTypeœ:œAgentœ,œidœ:œAgent-b9Ndrœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-E20qD{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-E20qDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-b9Ndr", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-b9Ndrœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-E20qD", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-E20qDœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-opLbj", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "finance_agent_output", - "id": "Prompt-cisfj", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-opLbj{œdataTypeœ:œAgentœ,œidœ:œAgent-opLbjœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-cisfj{œfieldNameœ:œfinance_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-opLbj", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-opLbjœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-cisfj", - "targetHandle": "{œfieldNameœ:œfinance_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-hE8ZA", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-AngMf", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-hE8ZA{œdataTypeœ:œChatInputœ,œidœ:œChatInput-hE8ZAœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-AngMf{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-hE8ZA", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-hE8ZAœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-AngMf", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-IG0jU", - "name": "prompt", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-AngMf", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-IG0jU{œdataTypeœ:œPromptœ,œidœ:œPrompt-IG0jUœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-AngMf{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-IG0jU", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-IG0jUœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-AngMf", - "targetHandle": "{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TavilyAISearch", - "id": "TavilyAISearch-KZP5i", - "name": "api_build_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-AngMf", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-TavilyAISearch-KZP5i{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-KZP5iœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-AngMf{œfieldNameœ:œtoolsœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "TavilyAISearch-KZP5i", - "sourceHandle": "{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-KZP5iœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-AngMf", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-AngMfœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-AngMf", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-opLbj", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-AngMf{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-opLbj{œfieldNameœ:œinput_valueœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-AngMf", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-opLbj", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-AngMf", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "research_agent_output", - "id": "Prompt-cisfj", - "inputTypes": ["Message", "Text"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-AngMf{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-cisfj{œfieldNameœ:œresearch_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-AngMf", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-AngMfœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-cisfj", - "targetHandle": "{œfieldNameœ:œresearch_agent_outputœ,œidœ:œPrompt-cisfjœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "source": "CalculatorComponent-ZUJg0", - "sourceHandle": "{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-ZUJg0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-b9Ndr", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-b9Ndr", - "inputTypes": ["Tool"], - "type": "other" - }, - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-ZUJg0", - "name": "component_as_tool", - "output_types": ["Tool"] - } - }, - "id": "xy-edge__CalculatorComponent-ZUJg0{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-ZUJg0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-b9Ndr{œfieldNameœ:œtoolsœ,œidœ:œAgent-b9Ndrœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "source": "YfinanceComponent-gHp4w", - "sourceHandle": "{œdataTypeœ:œYfinanceComponentœ,œidœ:œYfinanceComponent-gHp4wœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-opLbj", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-opLbj", - "inputTypes": ["Tool"], - "type": "other" - }, - "sourceHandle": { - "dataType": "YfinanceComponent", - "id": "YfinanceComponent-gHp4w", - "name": "component_as_tool", - "output_types": ["Tool"] - } - }, - "id": "xy-edge__YfinanceComponent-gHp4w{œdataTypeœ:œYfinanceComponentœ,œidœ:œYfinanceComponent-gHp4wœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-opLbj{œfieldNameœ:œtoolsœ,œidœ:œAgent-opLbjœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" + "type": "genericNode" } ], "viewport": { @@ -3662,5 +3918,9 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Sequential Tasks Agents", - "tags": ["assistants", "agents", "web-scraping"] -} + "tags": [ + "assistants", + "agents", + "web-scraping" + ] +} \ No newline at end of file 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 4171ca46b..3940f366b 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 @@ -1,5 +1,89 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-Hr2If", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-BStBJ", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-Hr2If{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Hr2Ifœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-BStBJ{œfieldNameœ:œinput_valueœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-Hr2If", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Hr2Ifœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-BStBJ", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-BStBJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-BStBJ", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-c2K0x", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-BStBJ{œdataTypeœ:œAgentœ,œidœ:œAgent-BStBJœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-c2K0x{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-c2K0xœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Agent-BStBJ", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-BStBJœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-c2K0x", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-c2K0xœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "dataType": "CalculatorComponent", + "id": "CalculatorComponent-RGZ02", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-BStBJ", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-CalculatorComponent-RGZ02{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-RGZ02œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-BStBJ{œfieldNameœ:œtoolsœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "CalculatorComponent-RGZ02", + "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-RGZ02œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-BStBJ", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-BStBJœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { @@ -7,7 +91,9 @@ "display_name": "Agent", "id": "Agent-BStBJ", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -56,7 +142,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -85,7 +173,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -134,7 +224,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -185,7 +277,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -259,7 +353,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -353,7 +449,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -387,7 +486,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -403,7 +506,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -423,7 +528,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -443,7 +550,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -480,7 +589,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -501,7 +612,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -550,7 +663,9 @@ "data": { "id": "ChatInput-Hr2If", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -582,7 +697,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -595,7 +712,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -615,7 +734,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -718,7 +839,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -734,7 +858,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -754,7 +880,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -790,7 +918,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -828,7 +958,9 @@ "display_name": "Chat Output", "id": "ChatOutput-c2K0x", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -860,7 +992,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -873,7 +1007,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -893,7 +1029,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -931,7 +1069,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -951,7 +1091,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -972,7 +1114,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -988,7 +1133,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1008,7 +1155,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1044,7 +1193,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -1081,185 +1232,208 @@ "display_name": "URL", "id": "URL-Cns6P", "node": { + "base_classes": [ + "Data", + "DataFrame", + "Message" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Load and retrive data from specified URLs.", + "display_name": "URL", + "documentation": "", + "edited": false, + "field_order": [ + "urls", + "format" + ], + "frozen": false, + "icon": "layout-template", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "import re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Load and retrive data from specified URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n is_list=True,\n tool_mode=True,\n placeholder=\"Enter a URL...\",\n list_add_label=\"Add URL\",\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Message\", name=\"text\", method=\"fetch_content_text\"),\n Output(display_name=\"DataFrame\", name=\"dataframe\", method=\"as_dataframe\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n msg = f\"Invalid URL: {string}\"\n raise ValueError(msg)\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n if self.format == \"Raw HTML\":\n loader = AsyncHtmlLoader(web_path=urls, encoding=\"utf-8\")\n else:\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n\n def as_dataframe(self) -> DataFrame:\n return DataFrame(self.fetch_content())\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Load and retrive data from specified URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n is_list=True,\n tool_mode=True,\n placeholder=\"Enter a URL...\",\n list_add_label=\"Add URL\",\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"Message\", name=\"text\", method=\"fetch_content_text\"),\n Output(display_name=\"DataFrame\", name=\"dataframe\", method=\"as_dataframe\"),\n ]\n\n def ensure_url(self, string: str) -> str:\n \"\"\"Ensures the given string is a URL by adding 'http://' if it doesn't start with 'http://' or 'https://'.\n\n Raises an error if the string is not a valid URL.\n\n Parameters:\n string (str): The string to be checked and possibly modified.\n\n Returns:\n str: The modified string that is ensured to be a URL.\n\n Raises:\n ValueError: If the string is not a valid URL.\n \"\"\"\n if not string.startswith((\"http://\", \"https://\")):\n string = \"http://\" + string\n\n # Basic URL validation regex\n url_regex = re.compile(\n r\"^(https?:\\/\\/)?\" # optional protocol\n r\"(www\\.)?\" # optional www\n r\"([a-zA-Z0-9.-]+)\" # domain\n r\"(\\.[a-zA-Z]{2,})?\" # top-level domain\n r\"(:\\d+)?\" # optional port\n r\"(\\/[^\\s]*)?$\", # optional path\n re.IGNORECASE,\n )\n\n if not url_regex.match(string):\n msg = f\"Invalid URL: {string}\"\n raise ValueError(msg)\n\n return string\n\n def fetch_content(self) -> list[Data]:\n urls = [self.ensure_url(url.strip()) for url in self.urls if url.strip()]\n if self.format == \"Raw HTML\":\n loader = AsyncHtmlLoader(web_path=urls, encoding=\"utf-8\")\n else:\n loader = WebBaseLoader(web_paths=urls, encoding=\"utf-8\")\n docs = loader.load()\n data = [Data(text=doc.page_content, **doc.metadata) for doc in docs]\n self.status = data\n return data\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n\n def as_dataframe(self) -> DataFrame:\n return DataFrame(self.fetch_content())\n" }, "format": { - "tool_mode": false, - "trace_as_metadata": true, - "options": ["Text", "Raw HTML"], - "combobox": false, - "required": false, - "placeholder": "", - "show": true, - "name": "format", - "value": "Text", - "display_name": "Output Format", + "_input_type": "DropdownInput", "advanced": false, + "combobox": false, + "display_name": "Output Format", "dynamic": false, "info": "Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.", - "title_case": false, - "type": "str", - "_input_type": "DropdownInput" - }, - "urls": { - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": true, - "list_add_label": "Add URL", + "name": "format", + "options": [ + "Text", + "Raw HTML" + ], + "placeholder": "", "required": false, - "placeholder": "Enter a URL...", "show": true, - "name": "urls", - "value": "", - "display_name": "URLs", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "", "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, "type": "str", - "_input_type": "MessageTextInput" + "value": "Text" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, "table_icon": "Hammer", "table_options": { "block_add": true, "block_delete": true, "block_edit": true, - "block_sort": true, "block_filter": true, "block_hide": true, "block_select": true, - "hide_options": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." + "hide_options": true }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "URL-fetch_content", "description": "fetch_content() - Load and retrive data from specified URLs.", - "tags": ["URL-fetch_content"] + "name": "URL-fetch_content", + "tags": [ + "URL-fetch_content" + ] }, { - "name": "URL-fetch_content_text", "description": "fetch_content_text() - Load and retrive data from specified URLs.", - "tags": ["URL-fetch_content_text"] + "name": "URL-fetch_content_text", + "tags": [ + "URL-fetch_content_text" + ] }, { - "name": "URL-as_dataframe", "description": "as_dataframe() - Load and retrive data from specified URLs.", - "tags": ["URL-as_dataframe"] + "name": "URL-as_dataframe", + "tags": [ + "URL-as_dataframe" + ] } - ], - "display_name": "Edit tools", + ] + }, + "urls": { + "_input_type": "MessageTextInput", "advanced": false, + "display_name": "URLs", "dynamic": false, "info": "", - "real_time_refresh": true, + "input_types": [ + "Message" + ], + "list": true, + "list_add_label": "Add URL", + "load_from_db": false, + "name": "urls", + "placeholder": "Enter a URL...", + "required": false, + "show": true, "title_case": false, - "type": "table", - "_input_type": "TableInput" + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" } }, - "description": "Load and retrive data from specified URLs.", - "icon": "layout-template", - "base_classes": ["Data", "DataFrame", "Message"], - "display_name": "URL", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": null - } - ], - "field_order": ["urls", "format"], - "beta": false, - "legacy": false, - "edited": false, - "metadata": {}, "tool_mode": true }, "type": "URL" @@ -1332,7 +1506,9 @@ "data": { "id": "CalculatorComponent-RGZ02", "node": { - "base_classes": ["Data"], + "base_classes": [ + "Data" + ], "beta": false, "category": "tools", "conditional_paths": [], @@ -1341,7 +1517,9 @@ "display_name": "Calculator", "documentation": "", "edited": false, - "field_order": ["expression"], + "field_order": [ + "expression" + ], "frozen": false, "icon": "calculator", "key": "CalculatorComponent", @@ -1352,15 +1530,17 @@ "output_types": [], "outputs": [ { - "types": ["Tool"], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", "cache": true, - "required_inputs": null + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" } ], "pinned": false, @@ -1391,7 +1571,9 @@ "display_name": "Expression", "dynamic": false, "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "list_add_label": "Add More", "load_from_db": false, @@ -1407,84 +1589,89 @@ "value": "" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", - "table_schema": { - "columns": [ - { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Specify the name of the tool.", - "disable_edit": false, - "edit_mode": "inline", - "formatter": "text" - }, - { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", - "description": "Describe the purpose of the tool.", - "disable_edit": false, - "edit_mode": "popover", - "formatter": "text" - }, - { - "name": "tags", - "display_name": "Tool Identifiers", - "sortable": false, - "filterable": false, - "type": "text", - "description": "The default identifiers for the tools and cannot be changed.", - "disable_edit": true, - "edit_mode": "inline", - "formatter": "text" - } - ] - }, - "trigger_text": "", - "trigger_icon": "Hammer", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, "table_icon": "Hammer", "table_options": { "block_add": true, "block_delete": true, "block_edit": true, - "block_sort": true, "block_filter": true, "block_hide": true, "block_select": true, - "hide_options": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", "field_parsers": { - "name": ["snake_case", "no_blank"], - "commands": "commands" + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] }, - "description": "Modify tool names and descriptions to help agents understand when to use each tool." + "hide_options": true }, + "table_schema": { + "columns": [ + { + "description": "Specify the name of the tool.", + "disable_edit": false, + "display_name": "Tool Name", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" + }, + { + "description": "Describe the purpose of the tool.", + "disable_edit": false, + "display_name": "Tool Description", + "edit_mode": "popover", + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "text" + }, + { + "description": "The default identifiers for the tools and cannot be changed.", + "disable_edit": true, + "display_name": "Tool Identifiers", + "edit_mode": "inline", + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" + } + ] + }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", "name": "None-evaluate_expression", - "tags": ["None-evaluate_expression"] + "tags": [ + "None-evaluate_expression" + ] } - ], - "display_name": "Edit tools", - "advanced": false, - "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" + ] } }, "tool_mode": true @@ -1506,78 +1693,6 @@ "type": "genericNode" } ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-Hr2If", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-BStBJ", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-Hr2If{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Hr2Ifœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-BStBJ{œfieldNameœ:œinput_valueœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-Hr2If", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Hr2Ifœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-BStBJ", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-BStBJ", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-c2K0x", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-BStBJ{œdataTypeœ:œAgentœ,œidœ:œAgent-BStBJœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-c2K0x{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-c2K0xœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Agent-BStBJ", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-BStBJœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-c2K0x", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-c2K0xœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-RGZ02", - "name": "component_as_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-BStBJ", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-CalculatorComponent-RGZ02{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-RGZ02œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-BStBJ{œfieldNameœ:œtoolsœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "CalculatorComponent-RGZ02", - "sourceHandle": "{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-RGZ02œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-BStBJ", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-BStBJœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "className": "" - } - ], "viewport": { "x": -573.0285266811966, "y": 96.72381189311284, @@ -1590,5 +1705,8 @@ "is_component": false, "last_tested_version": "1.1.1", "name": "Simple Agent", - "tags": ["assistants", "agents"] -} + "tags": [ + "assistants", + "agents" + ] +} \ No newline at end of file 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 a8da3a34a..679cd153b 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 @@ -1,11 +1,204 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-AiQA7", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-UWiDB", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-AiQA7{œdataTypeœ:œAgentœ,œidœ:œAgent-AiQA7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-UWiDB{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-UWiDBœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-AiQA7", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-AiQA7œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-UWiDB", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-UWiDBœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-ArtN4", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-AiQA7", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-ArtN4{œdataTypeœ:œAgentœ,œidœ:œAgent-ArtN4œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-AiQA7{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-ArtN4", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-ArtN4œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-AiQA7", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-AiQA7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-ZZ1QV", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-ArtN4", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-ZZ1QV{œdataTypeœ:œAgentœ,œidœ:œAgent-ZZ1QVœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-ArtN4{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Agent-ZZ1QV", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-ZZ1QVœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-ArtN4", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-ArtN4œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "SearchAPI", + "id": "SearchAPI-KMYDO", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-ZZ1QV", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-SearchAPI-KMYDO{œdataTypeœ:œSearchAPIœ,œidœ:œSearchAPI-KMYDOœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-ZZ1QV{œfieldNameœ:œtoolsœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "SearchAPI-KMYDO", + "sourceHandle": "{œdataTypeœ: œSearchAPIœ, œidœ: œSearchAPI-KMYDOœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-ZZ1QV", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-ZZ1QVœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "url_content_fetcher", + "id": "url_content_fetcher-vZFfk", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-ArtN4", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-url_content_fetcher-vZFfk{œdataTypeœ:œurl_content_fetcherœ,œidœ:œurl_content_fetcher-vZFfkœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-ArtN4{œfieldNameœ:œtoolsœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "url_content_fetcher-vZFfk", + "sourceHandle": "{œdataTypeœ: œurl_content_fetcherœ, œidœ: œurl_content_fetcher-vZFfkœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-ArtN4", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-ArtN4œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "CalculatorTool", + "id": "CalculatorTool-LJZFv", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-AiQA7", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-CalculatorTool-LJZFv{œdataTypeœ:œCalculatorToolœ,œidœ:œCalculatorTool-LJZFvœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-AiQA7{œfieldNameœ:œtoolsœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "CalculatorTool-LJZFv", + "sourceHandle": "{œdataTypeœ: œCalculatorToolœ, œidœ: œCalculatorTool-LJZFvœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-AiQA7", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-AiQA7œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-onw3j", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-ZZ1QV", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-onw3j{œdataTypeœ:œChatInputœ,œidœ:œChatInput-onw3jœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-ZZ1QV{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-onw3j", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-onw3jœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-ZZ1QV", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-ZZ1QVœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], "nodes": [ { "data": { "id": "ChatInput-onw3j", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -34,7 +227,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -47,7 +242,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -66,7 +263,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -167,7 +366,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -182,7 +384,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -201,7 +405,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -236,7 +442,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -256,6 +464,10 @@ "dragging": false, "height": 262, "id": "ChatInput-onw3j", + "measured": { + "height": 262, + "width": 320 + }, "position": { "x": 1756.77096149088, "y": 292.73476765276695 @@ -266,11 +478,7 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 262 - } + "width": 360 }, { "data": { @@ -278,7 +486,9 @@ "display_name": "Chat Output", "id": "ChatOutput-UWiDB", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -310,7 +520,9 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -323,7 +535,9 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "background_color", @@ -343,7 +557,9 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "chat_icon", @@ -381,7 +597,9 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "data_template", @@ -401,7 +619,9 @@ "display_name": "Text", "dynamic": false, "info": "Message to be passed as output.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -422,7 +642,10 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "placeholder": "", "required": false, "show": true, @@ -438,7 +661,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -458,7 +683,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -494,7 +721,9 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "text_color", @@ -516,6 +745,10 @@ "dragging": false, "height": 262, "id": "ChatOutput-UWiDB", + "measured": { + "height": 262, + "width": 320 + }, "position": { "x": 4349.229697347143, "y": 620.5490494265098 @@ -526,184 +759,25 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 262 - } + "width": 360 }, { "data": { + "description": "Call the searchapi.io API with result limiting", + "display_name": "Search API [DEPRECATED]", "id": "SearchAPI-KMYDO", "node": { - "template": { - "_type": "Component", - "api_key": { - "load_from_db": false, - "required": true, - "placeholder": "", - "show": true, - "name": "api_key", - "value": "", - "display_name": "SearchAPI API Key", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "", - "title_case": false, - "password": true, - "type": "str", - "_input_type": "SecretStrInput" - }, - "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API [DEPRECATED]\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n icon = \"SearchAPI\"\n legacy = True\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", - "advanced": true, - "dynamic": true, - "info": "", - "load_from_db": false, - "title_case": false - }, - "engine": { - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "engine", - "value": "google", - "display_name": "Engine", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "", - "title_case": false, - "type": "str", - "_input_type": "MessageTextInput" - }, - "input_value": { - "tool_mode": false, - "trace_as_input": true, - "multiline": true, - "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "input_value", - "value": "langflow docs", - "display_name": "Input", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "", - "title_case": false, - "type": "str", - "_input_type": "MultilineInput" - }, - "max_results": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "max_results", - "value": 5, - "display_name": "Max Results", - "advanced": true, - "dynamic": false, - "info": "", - "title_case": false, - "type": "int", - "_input_type": "IntInput" - }, - "max_snippet_length": { - "tool_mode": false, - "trace_as_metadata": true, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "max_snippet_length", - "value": 100, - "display_name": "Max Snippet Length", - "advanced": true, - "dynamic": false, - "info": "", - "title_case": false, - "type": "int", - "_input_type": "IntInput" - }, - "search_params": { - "tool_mode": false, - "trace_as_input": true, - "list": true, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "search_params", - "value": {}, - "display_name": "Search parameters", - "advanced": true, - "dynamic": false, - "info": "", - "title_case": false, - "type": "dict", - "_input_type": "DictInput" - } - }, + "base_classes": [ + "Data", + "Tool" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, "description": "Call the searchapi.io API with result limiting", - "icon": "SearchAPI", - "base_classes": ["Data", "Tool"], "display_name": "Search API [DEPRECATED]", "documentation": "https://www.searchapi.io/docs/google", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Data"], - "selected": "Data", - "name": "api_run_model", - "display_name": "Data", - "method": "run_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - }, - { - "types": ["Tool"], - "selected": "Tool", - "name": "api_build_tool", - "display_name": "Tool", - "method": "build_tool", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": ["api_key"] - } - ], + "edited": false, "field_order": [ "engine", "api_key", @@ -712,19 +786,195 @@ "max_results", "max_snippet_length" ], - "beta": false, + "frozen": false, + "icon": "SearchAPI", "legacy": true, - "edited": false, "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "method": "run_model", + "name": "api_run_model", + "required_inputs": [ + "api_key" + ], + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Tool", + "method": "build_tool", + "name": "api_build_tool", + "required_inputs": [ + "api_key" + ], + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "template": { + "_type": "Component", + "api_key": { + "_input_type": "SecretStrInput", + "advanced": false, + "display_name": "SearchAPI API Key", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "load_from_db": false, + "name": "api_key", + "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API [DEPRECATED]\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n icon = \"SearchAPI\"\n legacy = True\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" + }, + "engine": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Engine", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "engine", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "google" + }, + "input_value": { + "_input_type": "MultilineInput", + "advanced": false, + "display_name": "Input", + "dynamic": false, + "info": "", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "multiline": true, + "name": "input_value", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "langflow docs" + }, + "max_results": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Results", + "dynamic": false, + "info": "", + "list": false, + "list_add_label": "Add More", + "name": "max_results", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 5 + }, + "max_snippet_length": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Snippet Length", + "dynamic": false, + "info": "", + "list": false, + "list_add_label": "Add More", + "name": "max_snippet_length", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 100 + }, + "search_params": { + "_input_type": "DictInput", + "advanced": true, + "display_name": "Search parameters", + "dynamic": false, + "info": "", + "list": true, + "list_add_label": "Add More", + "name": "search_params", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "type": "dict", + "value": {} + } + }, "tool_mode": false }, - "type": "SearchAPI", - "description": "Call the searchapi.io API with result limiting", - "display_name": "Search API [DEPRECATED]" + "type": "SearchAPI" }, "dragging": false, "height": 509, "id": "SearchAPI-KMYDO", + "measured": { + "height": 509, + "width": 320 + }, "position": { "x": 2101.519951743063, "y": 949.7032293566349 @@ -735,17 +985,17 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 509 - } + "width": 360 }, { "data": { "id": "url_content_fetcher-vZFfk", "node": { - "base_classes": ["Data", "list", "Tool"], + "base_classes": [ + "Data", + "list", + "Tool" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -753,7 +1003,10 @@ "display_name": "URL Content Fetcher", "documentation": "https://python.langchain.com/docs/modules/data_connection/document_loaders/integrations/web_base", "edited": true, - "field_order": ["url", "fetch_params"], + "field_order": [ + "url", + "fetch_params" + ], "frozen": false, "icon": "globe", "lf_version": "1.0.19.post2", @@ -767,7 +1020,10 @@ "method": "run_model", "name": "api_run_model", "selected": "Data", - "types": ["Data", "list"], + "types": [ + "Data", + "list" + ], "value": "__UNDEFINED__" }, { @@ -776,7 +1032,9 @@ "method": "build_tool", "name": "api_build_tool", "selected": "Tool", - "types": ["Tool"], + "types": [ + "Tool" + ], "value": "__UNDEFINED__" } ], @@ -823,7 +1081,9 @@ "display_name": "URL", "dynamic": false, "info": "Enter a single URL to fetch content from.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "url", @@ -843,6 +1103,10 @@ "dragging": false, "height": 262, "id": "url_content_fetcher-vZFfk", + "measured": { + "height": 262, + "width": 320 + }, "position": { "x": 2834.525991812012, "y": 939.6518333549263 @@ -853,105 +1117,116 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 262 - } + "width": 360 }, { "data": { + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator [DEPRECATED]", "id": "CalculatorTool-LJZFv", "node": { + "base_classes": [ + "Data", + "Tool" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator [DEPRECATED]", + "documentation": "", + "edited": false, + "field_order": [ + "expression" + ], + "frozen": false, + "icon": "calculator", + "legacy": true, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "method": "run_model", + "name": "api_run_model", + "required_inputs": [], + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Tool", + "method": "build_tool", + "name": "api_build_tool", + "required_inputs": [], + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, "template": { "_type": "Component", "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "import ast\nimport operator\n\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import MessageTextInput\nfrom langflow.schema import Data\n\n\nclass CalculatorToolComponent(LCToolComponent):\n display_name = \"Calculator [DEPRECATED]\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n name = \"CalculatorTool\"\n legacy = True\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n ),\n ]\n\n class CalculatorToolSchema(BaseModel):\n expression: str = Field(..., description=\"The arithmetic expression to evaluate.\")\n\n def run_model(self) -> list[Data]:\n return self._evaluate_expression(self.expression)\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"calculator\",\n description=\"Evaluate basic arithmetic expressions. Input should be a string containing the expression.\",\n func=self._eval_expr_with_error,\n args_schema=self.CalculatorToolSchema,\n )\n\n def _eval_expr(self, node):\n if isinstance(node, ast.Num):\n return node.n\n if isinstance(node, ast.BinOp):\n left_val = self._eval_expr(node.left)\n right_val = self._eval_expr(node.right)\n return self.operators[type(node.op)](left_val, right_val)\n if isinstance(node, ast.UnaryOp):\n operand_val = self._eval_expr(node.operand)\n return self.operators[type(node.op)](operand_val)\n if isinstance(node, ast.Call):\n msg = (\n \"Function calls like sqrt(), sin(), cos() etc. are not supported. \"\n \"Only basic arithmetic operations (+, -, *, /, **) are allowed.\"\n )\n raise TypeError(msg)\n msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(msg)\n\n def _eval_expr_with_error(self, expression: str) -> list[Data]:\n try:\n return self._evaluate_expression(expression)\n except Exception as e:\n raise ToolException(str(e)) from e\n\n def _evaluate_expression(self, expression: str) -> list[Data]:\n try:\n # Parse the expression and evaluate it\n tree = ast.parse(expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n # Format the result to a reasonable number of decimal places\n formatted_result = f\"{result:.6f}\".rstrip(\"0\").rstrip(\".\")\n\n self.status = formatted_result\n return [Data(data={\"result\": formatted_result})]\n\n except (SyntaxError, TypeError, KeyError) as e:\n error_message = f\"Invalid expression: {e}\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n except Exception as e: # noqa: BLE001\n logger.opt(exception=True).debug(\"Error evaluating expression\")\n error_message = f\"Error: {e}\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.operators = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import ast\nimport operator\n\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import MessageTextInput\nfrom langflow.schema import Data\n\n\nclass CalculatorToolComponent(LCToolComponent):\n display_name = \"Calculator [DEPRECATED]\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n name = \"CalculatorTool\"\n legacy = True\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n ),\n ]\n\n class CalculatorToolSchema(BaseModel):\n expression: str = Field(..., description=\"The arithmetic expression to evaluate.\")\n\n def run_model(self) -> list[Data]:\n return self._evaluate_expression(self.expression)\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"calculator\",\n description=\"Evaluate basic arithmetic expressions. Input should be a string containing the expression.\",\n func=self._eval_expr_with_error,\n args_schema=self.CalculatorToolSchema,\n )\n\n def _eval_expr(self, node):\n if isinstance(node, ast.Num):\n return node.n\n if isinstance(node, ast.BinOp):\n left_val = self._eval_expr(node.left)\n right_val = self._eval_expr(node.right)\n return self.operators[type(node.op)](left_val, right_val)\n if isinstance(node, ast.UnaryOp):\n operand_val = self._eval_expr(node.operand)\n return self.operators[type(node.op)](operand_val)\n if isinstance(node, ast.Call):\n msg = (\n \"Function calls like sqrt(), sin(), cos() etc. are not supported. \"\n \"Only basic arithmetic operations (+, -, *, /, **) are allowed.\"\n )\n raise TypeError(msg)\n msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(msg)\n\n def _eval_expr_with_error(self, expression: str) -> list[Data]:\n try:\n return self._evaluate_expression(expression)\n except Exception as e:\n raise ToolException(str(e)) from e\n\n def _evaluate_expression(self, expression: str) -> list[Data]:\n try:\n # Parse the expression and evaluate it\n tree = ast.parse(expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n # Format the result to a reasonable number of decimal places\n formatted_result = f\"{result:.6f}\".rstrip(\"0\").rstrip(\".\")\n\n self.status = formatted_result\n return [Data(data={\"result\": formatted_result})]\n\n except (SyntaxError, TypeError, KeyError) as e:\n error_message = f\"Invalid expression: {e}\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n except Exception as e: # noqa: BLE001\n logger.opt(exception=True).debug(\"Error evaluating expression\")\n error_message = f\"Error: {e}\"\n self.status = error_message\n return [Data(data={\"error\": error_message, \"input\": expression})]\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.operators = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n" }, "expression": { + "_input_type": "MessageTextInput", + "advanced": false, + "display_name": "Expression", + "dynamic": false, + "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", + "input_types": [ + "Message" + ], + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "expression", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, "tool_mode": false, "trace_as_input": true, "trace_as_metadata": true, - "load_from_db": false, - "list": false, - "list_add_label": "Add More", - "required": false, - "placeholder": "", - "show": true, - "name": "expression", - "value": "2+2", - "display_name": "Expression", - "advanced": false, - "input_types": ["Message"], - "dynamic": false, - "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", - "title_case": false, "type": "str", - "_input_type": "MessageTextInput" + "value": "2+2" } }, - "description": "Perform basic arithmetic operations on a given expression.", - "icon": "calculator", - "base_classes": ["Data", "Tool"], - "display_name": "Calculator [DEPRECATED]", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": ["Data"], - "selected": "Data", - "name": "api_run_model", - "display_name": "Data", - "method": "run_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] - }, - { - "types": ["Tool"], - "selected": "Tool", - "name": "api_build_tool", - "display_name": "Tool", - "method": "build_tool", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [] - } - ], - "field_order": ["expression"], - "beta": false, - "legacy": true, - "edited": false, - "metadata": {}, "tool_mode": false }, - "type": "CalculatorTool", - "description": "Perform basic arithmetic operations on a given expression.", - "display_name": "Calculator [DEPRECATED]" + "type": "CalculatorTool" }, "dragging": false, "height": 338, "id": "CalculatorTool-LJZFv", + "measured": { + "height": 338, + "width": 320 + }, "position": { "x": 3546.599894399727, "y": 972.1522299506486 @@ -962,11 +1237,7 @@ }, "selected": true, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 338 - } + "width": 360 }, { "data": { @@ -974,7 +1245,9 @@ "display_name": "City Selection Agent", "id": "Agent-ZZ1QV", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1023,7 +1296,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1052,7 +1327,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1101,7 +1378,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -1152,7 +1431,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1226,7 +1507,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -1320,7 +1603,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -1354,7 +1640,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -1370,7 +1660,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1390,7 +1682,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1410,7 +1704,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1447,7 +1743,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1468,7 +1766,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -1503,6 +1803,10 @@ "dragging": true, "height": 725, "id": "Agent-ZZ1QV", + "measured": { + "height": 725, + "width": 320 + }, "position": { "x": 2472.7748760933105, "y": 335.66187210240537 @@ -1513,11 +1817,7 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 725 - } + "width": 360 }, { "data": { @@ -1525,7 +1825,9 @@ "display_name": "Local Expert Agent", "id": "Agent-ArtN4", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1574,7 +1876,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -1603,7 +1907,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1652,7 +1958,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -1703,7 +2011,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -1777,7 +2087,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -1871,7 +2183,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -1905,7 +2220,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -1921,7 +2240,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -1941,7 +2262,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -1961,7 +2284,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1998,7 +2323,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2019,7 +2346,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -2054,6 +2383,10 @@ "dragging": false, "height": 725, "id": "Agent-ArtN4", + "measured": { + "height": 725, + "width": 320 + }, "position": { "x": 3185.66991544494, "y": 355.95841004876377 @@ -2064,11 +2397,7 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 725 - } + "width": 360 }, { "data": { @@ -2076,7 +2405,9 @@ "display_name": "Travel Concierge Agent", "id": "Agent-AiQA7", "node": { - "base_classes": ["Message"], + "base_classes": [ + "Message" + ], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2125,7 +2456,9 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": ["Message"], + "types": [ + "Message" + ], "value": "__UNDEFINED__" } ], @@ -2154,7 +2487,9 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2203,7 +2538,9 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "load_from_db": false, "name": "api_key", "password": true, @@ -2254,7 +2591,9 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "input_value", @@ -2328,7 +2667,9 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": ["Memory"], + "input_types": [ + "Memory" + ], "list": false, "name": "memory", "placeholder": "", @@ -2422,7 +2763,10 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "placeholder": "", "required": false, "show": true, @@ -2456,7 +2800,11 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "placeholder": "", "required": false, "show": true, @@ -2472,7 +2820,9 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "sender_name", @@ -2492,7 +2842,9 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "name": "session_id", @@ -2512,7 +2864,9 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2549,7 +2903,9 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": ["Message"], + "input_types": [ + "Message" + ], "list": false, "load_from_db": false, "multiline": true, @@ -2570,7 +2926,9 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": ["Tool"], + "input_types": [ + "Tool" + ], "list": true, "name": "tools", "placeholder": "", @@ -2605,6 +2963,10 @@ "dragging": false, "height": 725, "id": "Agent-AiQA7", + "measured": { + "height": 725, + "width": 320 + }, "position": { "x": 3889.695953842898, "y": 370.3161168611889 @@ -2615,11 +2977,7 @@ }, "selected": false, "type": "genericNode", - "width": 360, - "measured": { - "width": 320, - "height": 725 - } + "width": 360 }, { "data": { @@ -2635,6 +2993,10 @@ "dragging": false, "height": 636, "id": "note-K6vDt", + "measured": { + "height": 636, + "width": 325 + }, "position": { "x": 1076.3710803600266, "y": 92.06058855045646 @@ -2650,11 +3012,7 @@ "width": 600 }, "type": "noteNode", - "width": 600, - "measured": { - "width": 325, - "height": 636 - } + "width": 600 }, { "data": { @@ -2672,6 +3030,10 @@ "dragging": false, "height": 362, "id": "note-kj8YE", + "measured": { + "height": 362, + "width": 325 + }, "position": { "x": 2122.4146132377227, "y": 485.2212661145467 @@ -2687,11 +3049,7 @@ "width": 331 }, "type": "noteNode", - "width": 331, - "measured": { - "width": 325, - "height": 362 - } + "width": 331 }, { "data": { @@ -2709,6 +3067,10 @@ "dragging": false, "height": 366, "id": "note-523ch", + "measured": { + "height": 366, + "width": 325 + }, "position": { "x": 2827.660803823376, "y": 488.6092281195304 @@ -2724,11 +3086,7 @@ "width": 351 }, "type": "noteNode", - "width": 351, - "measured": { - "width": 325, - "height": 366 - } + "width": 351 }, { "data": { @@ -2746,6 +3104,10 @@ "dragging": false, "height": 344, "id": "note-6RsAX", + "measured": { + "height": 344, + "width": 325 + }, "position": { "x": 3536.084279543714, "y": 496.3155992003396 @@ -2761,11 +3123,7 @@ "width": 344 }, "type": "noteNode", - "width": 344, - "measured": { - "width": 325, - "height": 344 - } + "width": 344 }, { "data": { @@ -2783,6 +3141,10 @@ "dragging": false, "height": 328, "id": "note-KT4sJ", + "measured": { + "height": 328, + "width": 325 + }, "position": { "x": 2463.3881993480218, "y": 42.83594355441298 @@ -2793,174 +3155,7 @@ }, "selected": false, "type": "noteNode", - "width": 328, - "measured": { - "width": 325, - "height": 328 - } - } - ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-AiQA7", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-UWiDB", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-AiQA7{œdataTypeœ:œAgentœ,œidœ:œAgent-AiQA7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-UWiDB{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-UWiDBœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-AiQA7", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-AiQA7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-UWiDB", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-UWiDBœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-ArtN4", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-AiQA7", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-ArtN4{œdataTypeœ:œAgentœ,œidœ:œAgent-ArtN4œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-AiQA7{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-ArtN4", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-ArtN4œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-AiQA7", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-ZZ1QV", - "name": "response", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-ArtN4", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-ZZ1QV{œdataTypeœ:œAgentœ,œidœ:œAgent-ZZ1QVœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-ArtN4{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-ZZ1QV", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-ZZ1QVœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-ArtN4", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "SearchAPI", - "id": "SearchAPI-KMYDO", - "name": "api_build_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-ZZ1QV", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-SearchAPI-KMYDO{œdataTypeœ:œSearchAPIœ,œidœ:œSearchAPI-KMYDOœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-ZZ1QV{œfieldNameœ:œtoolsœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "SearchAPI-KMYDO", - "sourceHandle": "{œdataTypeœ:œSearchAPIœ,œidœ:œSearchAPI-KMYDOœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-ZZ1QV", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "url_content_fetcher", - "id": "url_content_fetcher-vZFfk", - "name": "api_build_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-ArtN4", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-url_content_fetcher-vZFfk{œdataTypeœ:œurl_content_fetcherœ,œidœ:œurl_content_fetcher-vZFfkœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-ArtN4{œfieldNameœ:œtoolsœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "url_content_fetcher-vZFfk", - "sourceHandle": "{œdataTypeœ:œurl_content_fetcherœ,œidœ:œurl_content_fetcher-vZFfkœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-ArtN4", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-ArtN4œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "CalculatorTool", - "id": "CalculatorTool-LJZFv", - "name": "api_build_tool", - "output_types": ["Tool"] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-AiQA7", - "inputTypes": ["Tool"], - "type": "other" - } - }, - "id": "reactflow__edge-CalculatorTool-LJZFv{œdataTypeœ:œCalculatorToolœ,œidœ:œCalculatorTool-LJZFvœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-AiQA7{œfieldNameœ:œtoolsœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "CalculatorTool-LJZFv", - "sourceHandle": "{œdataTypeœ:œCalculatorToolœ,œidœ:œCalculatorTool-LJZFvœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-AiQA7", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-AiQA7œ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-onw3j", - "name": "message", - "output_types": ["Message"] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-ZZ1QV", - "inputTypes": ["Message"], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-onw3j{œdataTypeœ:œChatInputœ,œidœ:œChatInput-onw3jœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-ZZ1QV{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-onw3j", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-onw3jœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-ZZ1QV", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-ZZ1QVœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" + "width": 328 } ], "viewport": { @@ -2977,5 +3172,8 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Travel Planning Agents", - "tags": ["agents", "openai"] -} + "tags": [ + "agents", + "openai" + ] +} \ No newline at end of file