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 7a2515e07..3e066cd80 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,288 +1,11 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TextInput", - "id": "TextInput-KiwSm", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "guidelines", - "id": "Prompt-z6Dtw", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-TextInput-KiwSm{œdataTypeœ:œTextInputœ,œidœ:œTextInput-KiwSmœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-z6Dtw{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-z6Dtwœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "TextInput-KiwSm", - "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-KiwSmœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-z6Dtw", - "targetHandle": "{œfieldNameœ: œguidelinesœ, œidœ: œPrompt-z6Dtwœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-xATVJ", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-8vh0B", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-xATVJ{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-xATVJœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-8vh0B{œfieldNameœ:œpostœ,œidœ:œPrompt-8vh0Bœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-xATVJ", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-xATVJœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-8vh0B", - "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-8vh0Bœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-z6Dtw", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-xATVJ", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-z6Dtw{œdataTypeœ:œPromptœ,œidœ:œPrompt-z6Dtwœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-xATVJ{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-xATVJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-z6Dtw", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-z6Dtwœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-xATVJ", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-xATVJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-Nk5P9", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-IcxoG", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-Nk5P9{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Nk5P9œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-IcxoG{œfieldNameœ:œinput_valueœ,œidœ:œAgent-IcxoGœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-Nk5P9", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Nk5P9œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-IcxoG", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-IcxoGœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-IcxoG", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-z6Dtw", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-IcxoG{œdataTypeœ:œAgentœ,œidœ:œAgent-IcxoGœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-z6Dtw{œfieldNameœ:œcontextœ,œidœ:œPrompt-z6Dtwœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-IcxoG", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-IcxoGœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-z6Dtw", - "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-z6Dtwœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-8vh0B", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-z4zkm", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-8vh0B{œdataTypeœ:œPromptœ,œidœ:œPrompt-8vh0Bœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-z4zkm{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-z4zkmœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-8vh0B", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-8vh0Bœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-z4zkm", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-z4zkmœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-xATVJ", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-TzIMq", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-xATVJ{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-xATVJœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-TzIMq{œfieldNameœ:œpostœ,œidœ:œPrompt-TzIMqœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-xATVJ", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-xATVJœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-TzIMq", - "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-TzIMqœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": true, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-z4zkm", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "image_description", - "id": "Prompt-TzIMq", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-z4zkm{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-z4zkmœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-TzIMq{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-TzIMqœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-z4zkm", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-z4zkmœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-TzIMq", - "targetHandle": "{œfieldNameœ: œimage_descriptionœ, œidœ: œPrompt-TzIMqœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-TzIMq", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-XWD0l", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-TzIMq{œdataTypeœ:œPromptœ,œidœ:œPrompt-TzIMqœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-XWD0l{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-XWD0lœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-TzIMq", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-TzIMqœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-XWD0l", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-XWD0lœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-cw2iI", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-IcxoG", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "xy-edge__TavilySearchComponent-cw2iI{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-cw2iIœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-IcxoG{œfieldNameœ:œtoolsœ,œidœ:œAgent-IcxoGœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "TavilySearchComponent-cw2iI", - "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-cw2iIœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-IcxoG", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-IcxoGœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - } - ], "nodes": [ { "data": { - "id": "ChatInput-Nk5P9", + "id": "ChatInput-pvWq5", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -309,15 +32,13 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "message", "display_name": "Message", "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, @@ -329,9 +50,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -350,9 +69,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -366,22 +83,22 @@ "value": "" }, "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "files": { "_input_type": "FileInput", @@ -453,10 +170,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -471,9 +185,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -492,9 +204,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -529,9 +239,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -550,7 +258,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-Nk5P9", + "id": "ChatInput-pvWq5", "measured": { "height": 234, "width": 320 @@ -571,26 +279,19 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-z6Dtw", + "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, @@ -599,37 +300,35 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "prompt", "display_name": "Prompt Message", "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, "template": { "_type": "Component", "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "context": { "advanced": false, @@ -639,10 +338,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -662,10 +358,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -701,9 +394,7 @@ "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", @@ -724,7 +415,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-z6Dtw", + "id": "Prompt-j3woL", "measured": { "height": 433, "width": 320 @@ -743,11 +434,9 @@ }, { "data": { - "id": "TextInput-KiwSm", + "id": "TextInput-0rzBn", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -755,9 +444,7 @@ "display_name": "Text Input", "documentation": "", "edited": false, - "field_order": [ - "input_value" - ], + "field_order": ["input_value"], "frozen": false, "icon": "type", "legacy": false, @@ -766,37 +453,35 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "text", "display_name": "Message", "method": "text_response", - "name": "text", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, "template": { "_type": "Component", "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "input_value": { "_input_type": "MultilineInput", @@ -804,9 +489,7 @@ "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, @@ -826,7 +509,7 @@ }, "dragging": false, "height": 234, - "id": "TextInput-KiwSm", + "id": "TextInput-0rzBn", "measured": { "height": 234, "width": 320 @@ -847,12 +530,9 @@ "data": { "description": "Generates text using OpenAI LLMs.", "display_name": "OpenAI", - "id": "OpenAIModel-xATVJ", + "id": "OpenAIModel-jxXfH", "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], + "base_classes": ["LanguageModel", "Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -883,28 +563,24 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "text_output", "display_name": "Message", "method": "text_response", - "name": "text_output", - "required_inputs": [], - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": [] }, { - "cache": true, + "types": ["LanguageModel"], + "selected": "LanguageModel", + "name": "model_output", "display_name": "Language Model", "method": "build_model", - "name": "model_output", - "required_inputs": [], - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": [] } ], "pinned": false, @@ -916,9 +592,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": false, "name": "api_key", "password": true, @@ -930,22 +604,22 @@ "value": "" }, "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "input_value": { "_input_type": "MessageInput", @@ -953,9 +627,7 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1103,9 +775,7 @@ "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", @@ -1117,7 +787,7 @@ "trace_as_input": true, "trace_as_metadata": true, "type": "str", - "value": "" + "value": "langflow" }, "temperature": { "_input_type": "FloatInput", @@ -1142,7 +812,7 @@ }, "dragging": false, "height": 543, - "id": "OpenAIModel-xATVJ", + "id": "OpenAIModel-jxXfH", "measured": { "height": 543, "width": 320 @@ -1163,25 +833,19 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-8vh0B", + "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, @@ -1190,37 +854,35 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "prompt", "display_name": "Prompt Message", "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, "template": { "_type": "Component", "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "post": { "advanced": false, @@ -1230,10 +892,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -1269,9 +928,7 @@ "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", @@ -1292,7 +949,7 @@ }, "dragging": false, "height": 347, - "id": "Prompt-8vh0B", + "id": "Prompt-lqX5p", "measured": { "height": 347, "width": 320 @@ -1313,11 +970,9 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-XWD0l", + "id": "ChatOutput-CnabR", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1343,15 +998,13 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "message", "display_name": "Message", "method": "message_response", - "name": "message", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, @@ -1363,9 +1016,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -1385,9 +1036,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -1402,22 +1051,22 @@ "value": "" }, "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "data_template": { "_input_type": "MessageTextInput", @@ -1425,9 +1074,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -1447,9 +1094,7 @@ "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", @@ -1470,10 +1115,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -1489,9 +1131,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1511,9 +1151,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1549,9 +1187,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -1572,7 +1208,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-XWD0l", + "id": "ChatOutput-CnabR", "measured": { "height": 234, "width": 320 @@ -1593,11 +1229,9 @@ "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-IcxoG", + "id": "Agent-TG1G2", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1640,15 +1274,13 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "response", "display_name": "Response", "method": "message_response", - "name": "response", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, @@ -1676,9 +1308,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1727,9 +1357,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": false, "name": "api_key", "password": true, @@ -1741,22 +1369,22 @@ "value": "" }, "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "handle_parsing_errors": { "_input_type": "BoolInput", @@ -1780,9 +1408,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1856,9 +1482,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -1952,10 +1576,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -1989,11 +1610,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -2009,9 +1626,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -2031,9 +1646,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -2053,9 +1666,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2092,9 +1703,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2115,9 +1724,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -2151,7 +1758,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-IcxoG", + "id": "Agent-TG1G2", "measured": { "height": 650, "width": 320 @@ -2172,12 +1779,9 @@ "data": { "description": "Generates text using OpenAI LLMs.", "display_name": "OpenAI", - "id": "OpenAIModel-z4zkm", + "id": "OpenAIModel-Sef2w", "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], + "base_classes": ["LanguageModel", "Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2208,28 +1812,24 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "text_output", "display_name": "Message", "method": "text_response", - "name": "text_output", - "required_inputs": [], - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": [] }, { - "cache": true, + "types": ["LanguageModel"], + "selected": "LanguageModel", + "name": "model_output", "display_name": "Language Model", "method": "build_model", - "name": "model_output", - "required_inputs": [], - "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": [] } ], "pinned": false, @@ -2241,9 +1841,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": false, "name": "api_key", "password": true, @@ -2255,22 +1853,22 @@ "value": "" }, "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "input_value": { "_input_type": "MessageInput", @@ -2278,9 +1876,7 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -2428,9 +2024,7 @@ "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", @@ -2467,7 +2061,7 @@ }, "dragging": false, "height": 543, - "id": "OpenAIModel-z4zkm", + "id": "OpenAIModel-Sef2w", "measured": { "height": 543, "width": 320 @@ -2488,26 +2082,19 @@ "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-TzIMq", + "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, @@ -2516,37 +2103,35 @@ "output_types": [], "outputs": [ { - "cache": true, + "types": ["Message"], + "selected": "Message", + "name": "prompt", "display_name": "Prompt Message", "method": "build_prompt", - "name": "prompt", - "selected": "Message", - "types": [ - "Message" - ], - "value": "__UNDEFINED__" + "value": "__UNDEFINED__", + "cache": true } ], "pinned": false, "template": { "_type": "Component", "code": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "image_description": { "advanced": false, @@ -2556,10 +2141,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -2579,10 +2161,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -2618,9 +2197,7 @@ "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", @@ -2641,7 +2218,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-TzIMq", + "id": "Prompt-R2EK8", "measured": { "height": 433, "width": 320 @@ -2660,7 +2237,7 @@ }, { "data": { - "id": "note-WE2lo", + "id": "note-eNaIw", "node": { "description": "# Instagram Copywriter \n\nWelcome to the Instagram Copywriter! This flow helps you create compelling Instagram posts with AI-generated content and image prompts.\n\n## Instructions\n1. Enter Your Topic\n - In the Chat Input, enter a brief description of the topic you want to post about.\n - Example: \"Create a post about meditation and its benefits\"\n\n2. Review the Generated Content\n - The flow will use AI to research your topic and generate a formatted Instagram post.\n - The post will include an opening line, main content, emojis, a call-to-action, and hashtags.\n\n3. Check the Image Prompt\n - The flow will also generate a detailed image prompt based on your post content.\n - This prompt can be used with image generation tools to create a matching visual.\n\n4. Copy the Final Output\n - The Chat Output will display the complete Instagram post text followed by the image generation prompt.\n - Copy this output to use in your Instagram content creation process.\n\n5. Refine if Needed\n - If you're not satisfied with the result, you can adjust the input or modify the OpenAI model settings for different outputs.\n\nRemember: Keep your initial topic input clear and concise for best results! 🎨✨", "display_name": "", @@ -2673,7 +2250,7 @@ }, "dragging": false, "height": 648, - "id": "note-WE2lo", + "id": "note-eNaIw", "measured": { "height": 648, "width": 325 @@ -2697,7 +2274,7 @@ }, { "data": { - "id": "note-f8PDT", + "id": "note-HWvzc", "node": { "description": "**Text Input (Guidelines Prompt)**\n - NOTE: \"Contains Instagram post formatting rules. Don't modify this component as it maintains format consistency.\"\n - Maintains fixed guidelines for:\n * Opening structure\n * Main content\n * Emoji usage\n * Call to Action (CTA)\n * Hashtags\n\n4. **First Prompt + OpenAI Sequence**\n - NOTE: \"Generates initial post content following Instagram guidelines\"\n - Settings:\n * Temperature: 0.7 (good balance between creativity and consistency)\n * Input: Receives research context\n * Output: Generates formatted post text\n\n", "display_name": "", @@ -2710,7 +2287,7 @@ }, "dragging": false, "height": 325, - "id": "note-f8PDT", + "id": "note-HWvzc", "measured": { "height": 325, "width": 325 @@ -2730,7 +2307,7 @@ }, { "data": { - "id": "note-5ion3", + "id": "note-A4SZx", "node": { "description": "**Second Prompt + OpenAI Sequence**\n - NOTE: \"Transforms the generated post into a prompt for image generation\"\n - Settings:\n * Temperature: 0.7\n * Input: Receives generated post\n * Output: Creates detailed description for image generation\n\n", "display_name": "", @@ -2743,7 +2320,7 @@ }, "dragging": false, "height": 325, - "id": "note-5ion3", + "id": "note-A4SZx", "measured": { "height": 325, "width": 325 @@ -2762,7 +2339,7 @@ }, { "data": { - "id": "note-9U9ap", + "id": "note-RKey4", "node": { "description": "**Final Prompt**\n - NOTE: \"Combines Instagram post with image prompt in a final format\"\n - Structure:\n * First part: Complete Instagram post\n * Second part: Image generation prompt\n * Separator: Uses \"**Prompt:**\" to divide sections\n\n7. **Chat Output (Final Output)**\n - NOTE: \"Presents the combined final result that can be copied and used directly\"\n\nGENERAL USAGE TIPS:\n- Keep initial inputs clear and specific\n- Don't modify pre-defined Instagram guidelines\n- If style adjustments are needed, only modify the OpenAI models' temperature\n- Verify all connections are correct before running\n- Final result will always have two parts: post + image prompt\n\nFLOW CONSIDERATIONS:\n- All tools connect only to the Tool Calling Agent\n- The flow is unidirectional (no loops)\n- Each prompt template maintains specific formatting\n- Temperatures are set for optimal creativity/consistency balance\n\nTROUBLESHOOTING NOTES:\n- If output is too creative: Lower temperature", "display_name": "", @@ -2775,7 +2352,7 @@ }, "dragging": false, "height": 325, - "id": "note-9U9ap", + "id": "note-RKey4", "measured": { "height": 325, "width": 325 @@ -2794,7 +2371,7 @@ }, { "data": { - "id": "note-xpbyx", + "id": "note-sMyWp", "node": { "description": "# 🔑 Tavily AI Search Needs API Key\n\nYou can get 1000 searches/month free [here](https://tavily.com/) ", "display_name": "", @@ -2807,7 +2384,7 @@ }, "dragging": false, "height": 325, - "id": "note-xpbyx", + "id": "note-sMyWp", "measured": { "height": 325, "width": 325 @@ -2826,12 +2403,9 @@ }, { "data": { - "id": "TavilySearchComponent-cw2iI", + "id": "TavilySearchComponent-xQwoJ", "node": { - "base_classes": [ - "Data", - "Message" - ], + "base_classes": ["Data", "Message"], "beta": false, "category": "tools", "conditional_paths": [], @@ -2858,17 +2432,15 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Toolset", - "hidden": null, - "method": "to_toolkit", - "name": "component_as_tool", - "required_inputs": null, + "types": ["Tool"], "selected": "Tool", - "types": [ - "Tool" - ], - "value": "__UNDEFINED__" + "name": "component_as_tool", + "hidden": null, + "display_name": "Toolset", + "method": "to_toolkit", + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": null } ], "pinned": false, @@ -2881,9 +2453,7 @@ "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, @@ -2972,9 +2542,7 @@ "display_name": "Search Query", "dynamic": false, "info": "The search query you want to execute with Tavily.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "list_add_label": "Add More", "load_from_db": false, @@ -2997,10 +2565,7 @@ "dynamic": false, "info": "The depth of the search.", "name": "search_depth", - "options": [ - "basic", - "advanced" - ], + "options": ["basic", "advanced"], "placeholder": "", "required": false, "show": true, @@ -3011,107 +2576,89 @@ "value": "advanced" }, "tools_metadata": { - "_input_type": "TableInput", - "advanced": false, - "display_name": "Edit tools", - "dynamic": false, - "info": "", + "tool_mode": false, "is_list": true, "list_add_label": "Add More", - "name": "tools_metadata", - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, + "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, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "hide_options": true, "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] + "name": ["snake_case", "no_blank"], + "commands": "commands" }, - "hide_options": true + "description": "Modify tool names and descriptions to help agents understand when to use each tool." }, - "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" - }, - { - "description": "Add commands to the tool. These commands will be used to run the tool. Start all commands with a `/`. You can add multiple commands separated by a comma.\nExample: `/command1`, `/command2`, `/command3`", - "disable_edit": false, - "display_name": "Commands", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "commands", - "sortable": false, - "type": "text" - } - ] - }, - "title_case": false, - "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "required": false, + "placeholder": "", + "show": true, + "name": "tools_metadata", "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", @@ -3121,10 +2668,7 @@ "dynamic": false, "info": "The category of the search.", "name": "topic", - "options": [ - "general", - "news" - ], + "options": ["general", "news"], "placeholder": "", "required": false, "show": true, @@ -3134,15 +2678,16 @@ "type": "str", "value": "general" } - } + }, + "tool_mode": true }, "showNode": true, "type": "TavilySearchComponent" }, "dragging": false, - "id": "TavilySearchComponent-cw2iI", + "id": "TavilySearchComponent-xQwoJ", "measured": { - "height": 437, + "height": 435, "width": 320 }, "position": { @@ -3153,10 +2698,240 @@ "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": -2990.3235424557174, - "y": -1714.4878057543951, - "zoom": 0.6101920834254135 + "x": -1462.1369874897664, + "y": -557.4373796474765, + "zoom": 0.33990357996173937 } }, "description": " Create engaging Instagram posts with AI-generated content and image prompts, streamlining social media content creation.", @@ -3167,9 +2942,5 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Instagram Copywriter", - "tags": [ - "content-generation", - "chatbots", - "agents" - ] -} \ No newline at end of file + "tags": ["content-generation", "chatbots", "agents"] +} 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 a6746389e..4d5e3dda0 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,311 +1,23 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-Rc3MO", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "previous_response", - "id": "Prompt-u7GZR", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-Rc3MO{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Rc3MOœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-u7GZR{œfieldNameœ:œprevious_responseœ,œidœ:œPrompt-u7GZRœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-Rc3MO", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-Rc3MOœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-u7GZR", - "targetHandle": "{œfieldNameœ: œprevious_responseœ, œidœ: œPrompt-u7GZRœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-yDDjW", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-zhgF5", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-yDDjW{œdataTypeœ:œPromptœ,œidœ:œPrompt-yDDjWœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-zhgF5{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-zhgF5œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Prompt-yDDjW", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-yDDjWœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-zhgF5", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-zhgF5œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-Mzp4f", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Prompt-yDDjW", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-Mzp4f{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Mzp4fœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Prompt-yDDjW{œfieldNameœ:œinput_valueœ,œidœ:œPrompt-yDDjWœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-Mzp4f", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Mzp4fœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-yDDjW", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œPrompt-yDDjWœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-zhgF5", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-mWv8X", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-zhgF5{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-zhgF5œ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-mWv8X{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-mWv8Xœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "OpenAIModel-zhgF5", - "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-zhgF5œ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-mWv8X", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-mWv8Xœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TavilyAISearch", - "id": "TavilyAISearch-rI4aD", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-9E8IU", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-TavilyAISearch-rI4aD{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-rI4aDœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-9E8IU{œfieldNameœ:œtoolsœ,œidœ:œAgent-9E8IUœ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "selected": false, - "source": "TavilyAISearch-rI4aD", - "sourceHandle": "{œdataTypeœ: œTavilyAISearchœ, œidœ: œTavilyAISearch-rI4aDœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-9E8IU", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-9E8IUœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-u7GZR", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-9E8IU", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-u7GZR{œdataTypeœ:œPromptœ,œidœ:œPrompt-u7GZRœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-9E8IU{œfieldNameœ:œinput_valueœ,œidœ:œAgent-9E8IUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Prompt-u7GZR", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-u7GZRœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-9E8IU", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-9E8IUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-9E8IU", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "search_results", - "id": "Prompt-yDDjW", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-9E8IU{œdataTypeœ:œAgentœ,œidœ:œAgent-9E8IUœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-yDDjW{œfieldNameœ:œsearch_resultsœ,œidœ:œPrompt-yDDjWœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Agent-9E8IU", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-9E8IUœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-yDDjW", - "targetHandle": "{œfieldNameœ: œsearch_resultsœ, œidœ: œPrompt-yDDjWœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-T4lL6", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-Rc3MO", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-T4lL6{œdataTypeœ:œPromptœ,œidœ:œPrompt-T4lL6œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-Rc3MO{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-Rc3MOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-T4lL6", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-T4lL6œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-Rc3MO", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-Rc3MOœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-Mzp4f", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-Rc3MO", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-Mzp4f{œdataTypeœ:œChatInputœ,œidœ:œChatInput-Mzp4fœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-Rc3MO{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Rc3MOœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-Mzp4f", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-Mzp4fœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-Rc3MO", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-Rc3MOœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-f4xQ5", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_message", - "id": "OpenAIModel-zhgF5", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-f4xQ5{œdataTypeœ:œPromptœ,œidœ:œPrompt-f4xQ5œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-zhgF5{œfieldNameœ:œsystem_messageœ,œidœ:œOpenAIModel-zhgF5œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-f4xQ5", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-f4xQ5œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "OpenAIModel-zhgF5", - "targetHandle": "{œfieldNameœ: œsystem_messageœ, œidœ: œOpenAIModel-zhgF5œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], "nodes": [ { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-u7GZR", + "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, @@ -319,9 +31,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -354,10 +64,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -393,9 +100,7 @@ "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", @@ -416,7 +121,7 @@ }, "dragging": false, "height": 347, - "id": "Prompt-u7GZR", + "id": "Prompt-MTcxq", "position": { "x": 1803.2315476328304, "y": 839.0423490089254 @@ -427,15 +132,17 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 347 + } }, { "data": { - "id": "ChatInput-Mzp4f", + "id": "ChatInput-YWCg2", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "category": "inputs", "conditional_paths": [], @@ -469,9 +176,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -484,9 +189,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -505,9 +208,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -608,10 +309,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -626,9 +324,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -647,9 +343,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -684,9 +378,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -705,7 +397,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-Mzp4f", + "id": "ChatInput-YWCg2", "position": { "x": 756.0075981758582, "y": 756.7423476254241 @@ -716,17 +408,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 234 + } }, { "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-mWv8X", + "id": "ChatOutput-jGyp6", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -758,9 +452,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -773,9 +465,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -795,9 +485,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -835,9 +523,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -857,9 +543,7 @@ "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", @@ -880,10 +564,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -899,9 +580,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -921,9 +600,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -959,9 +636,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -982,7 +657,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-mWv8X", + "id": "ChatOutput-jGyp6", "position": { "x": 3200.774558432761, "y": 853.9881404769172 @@ -993,32 +668,29 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 234 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-yDDjW", + "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, @@ -1032,9 +704,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1067,10 +737,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -1090,10 +757,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -1129,9 +793,7 @@ "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", @@ -1152,7 +814,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-yDDjW", + "id": "Prompt-hBw61", "position": { "x": 2504.138359606453, "y": 434.061360540584 @@ -1163,25 +825,202 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 433 + } }, { "data": { "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", - "display_name": "Tavily AI Search", - "id": "TavilyAISearch-rI4aD", + "display_name": "Tavily AI Search [DEPRECATED]", + "id": "TavilyAISearch-wu6YR", "node": { - "base_classes": [ - "Data", - "Tool" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, + "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 + } + }, "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", - "display_name": "Tavily AI Search", + "icon": "TavilyIcon", + "base_classes": ["Data", "Tool"], + "display_name": "Tavily AI Search [DEPRECATED]", "documentation": "https://docs.tavily.com/", - "edited": false, + "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"] + } + ], "field_order": [ "api_key", "query", @@ -1191,204 +1030,17 @@ "include_images", "include_answer" ], - "frozen": false, - "icon": "TavilyIcon", - "legacy": false, - "lf_version": "1.0.19.post2", + "beta": false, + "legacy": true, + "edited": false, "metadata": {}, - "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\"\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\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, - "name": "include_answer", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "include_images", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "max_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "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" }, "dragging": false, "height": 481, - "id": "TavilyAISearch-rI4aD", + "id": "TavilyAISearch-wu6YR", "position": { "x": 1802.2291194402355, "y": 381.88177151343945 @@ -1397,20 +1049,21 @@ "x": 1802.2291194402355, "y": 381.88177151343945 }, - "selected": false, + "selected": true, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 481 + } }, { "data": { "description": "Generates text using OpenAI LLMs.", "display_name": "OpenAI", - "id": "OpenAIModel-Rc3MO", + "id": "OpenAIModel-wWNhZ", "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], + "base_classes": ["LanguageModel", "Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1447,9 +1100,7 @@ "name": "text_output", "required_inputs": [], "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" }, { @@ -1459,9 +1110,7 @@ "name": "model_output", "required_inputs": [], "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], + "types": ["LanguageModel"], "value": "__UNDEFINED__" } ], @@ -1474,9 +1123,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -1485,7 +1132,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1511,9 +1158,7 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1661,9 +1306,7 @@ "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", @@ -1700,7 +1343,7 @@ }, "dragging": false, "height": 630, - "id": "OpenAIModel-Rc3MO", + "id": "OpenAIModel-wWNhZ", "position": { "x": 1457.8987895868838, "y": 543.8838473503562 @@ -1711,18 +1354,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 630 + } }, { "data": { "description": "Generates text using OpenAI LLMs.", "display_name": "OpenAI", - "id": "OpenAIModel-zhgF5", + "id": "OpenAIModel-ILQV8", "node": { - "base_classes": [ - "LanguageModel", - "Message" - ], + "base_classes": ["LanguageModel", "Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1759,9 +1403,7 @@ "name": "text_output", "required_inputs": [], "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" }, { @@ -1771,9 +1413,7 @@ "name": "model_output", "required_inputs": [], "selected": "LanguageModel", - "types": [ - "LanguageModel" - ], + "types": ["LanguageModel"], "value": "__UNDEFINED__" } ], @@ -1786,9 +1426,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -1797,7 +1435,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1823,9 +1461,7 @@ "display_name": "Input", "dynamic": false, "info": "", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1973,9 +1609,7 @@ "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", @@ -2012,7 +1646,7 @@ }, "dragging": false, "height": 630, - "id": "OpenAIModel-zhgF5", + "id": "OpenAIModel-ILQV8", "position": { "x": 2860.2941186979524, "y": 561.8661152181708 @@ -2023,11 +1657,15 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 630 + } }, { "data": { - "id": "note-gBUJ9", + "id": "note-kzU8Y", "node": { "description": "# Research Agent \n\nWelcome to the Research Agent! This flow helps you conduct in-depth research on various topics using AI-powered tools and analysis.\n\n## Instructions\n1. Enter Your Research Query\n - Type your research question or topic into the Chat Input node.\n - Be specific and clear about what you want to investigate.\n\n2. Generate Research Plan\n - The system will create a focused research plan based on your query.\n - This plan includes key search queries and priorities.\n\n3. Conduct Web Search\n - The Tavily AI Search tool will perform web searches using the generated queries.\n - It focuses on finding academic and reliable sources.\n\n4. Analyze and Synthesize\n - The AI agent will review the search results and create a comprehensive synthesis.\n - The report includes an executive summary, methodology, findings, and conclusions.\n\n5. Review the Output\n - Read the final report in the Chat Output node.\n - Use this information as a starting point for further research or decision-making.\n\nRemember: You can refine your initial query for more specific results! 🔍📊", "display_name": "", @@ -2040,7 +1678,7 @@ }, "dragging": false, "height": 765, - "id": "note-gBUJ9", + "id": "note-kzU8Y", "position": { "x": 471.4335708918645, "y": -9.732869247334605 @@ -2056,17 +1694,19 @@ "width": 600 }, "type": "noteNode", - "width": 600 + "width": 600, + "measured": { + "width": 325, + "height": 765 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-9E8IU", + "id": "Agent-lD2aY", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2115,9 +1755,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2146,9 +1784,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2197,9 +1833,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -2208,7 +1842,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -2250,9 +1884,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -2326,9 +1958,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -2422,10 +2052,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -2459,11 +2086,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -2479,9 +2102,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -2501,9 +2122,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -2523,9 +2142,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2562,9 +2179,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2585,9 +2200,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -2621,7 +2234,7 @@ }, "dragging": false, "height": 658, - "id": "Agent-9E8IU", + "id": "Agent-lD2aY", "position": { "x": 2156.60686936856, "y": 439.4579572266066 @@ -2630,19 +2243,21 @@ "x": 2156.60686936856, "y": 439.4579572266066 }, - "selected": true, + "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 658 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-T4lL6", + "id": "Prompt-Unjx8", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": { @@ -2652,9 +2267,7 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": [ - "template" - ], + "field_order": ["template"], "frozen": false, "icon": "prompts", "legacy": false, @@ -2668,9 +2281,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2719,9 +2330,7 @@ "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", @@ -2742,7 +2351,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-T4lL6", + "id": "Prompt-Unjx8", "position": { "x": 1102.6079408836365, "y": 550.2148817052229 @@ -2753,17 +2362,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 260 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-f4xQ5", + "id": "Prompt-U0O7D", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": { @@ -2773,9 +2384,7 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": [ - "template" - ], + "field_order": ["template"], "frozen": false, "icon": "prompts", "legacy": false, @@ -2789,9 +2398,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2840,9 +2447,7 @@ "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", @@ -2863,7 +2468,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-f4xQ5", + "id": "Prompt-U0O7D", "position": { "x": 2498.9482347755306, "y": 889.7491088138673 @@ -2874,11 +2479,15 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 260 + } }, { "data": { - "id": "note-86Le6", + "id": "note-ZeCGk", "node": { "description": "# 🔑 Tavily AI Search Needs API Key\n\nYou can get 1000 searches/month free [here](https://tavily.com/) ", "display_name": "", @@ -2891,7 +2500,7 @@ }, "dragging": false, "height": 325, - "id": "note-86Le6", + "id": "note-ZeCGk", "position": { "x": 1797.5781951055678, "y": 206.30509875543274 @@ -2902,13 +2511,256 @@ }, "selected": false, "type": "noteNode", - "width": 325 + "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œ}" } ], "viewport": { - "x": -1627.3021649072248, - "y": -234.56097308583958, - "zoom": 0.9538000505518524 + "x": -135.41177004024598, + "y": 333.07279532015843, + "zoom": 0.4245328613083133 } }, "description": "Agent that generates focused plans, conducts web searches, and synthesizes findings into comprehensive reports.", @@ -2919,8 +2771,5 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Research Agent", - "tags": [ - "assistants", - "agents" - ] -} \ No newline at end of file + "tags": ["assistants", "agents"] +} 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 5bf1b96cd..ba1f2c39e 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,96 +1,13 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-HoULP", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-60t7m", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-HoULP{œdataTypeœ:œAgentœ,œidœ:œAgent-HoULPœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-60t7m{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-60t7mœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-HoULP", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-HoULPœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-60t7m", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-60t7mœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-nzVmM", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-HoULP", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-nzVmM{œdataTypeœ:œPromptœ,œidœ:œPrompt-nzVmMœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-HoULP{œfieldNameœ:œinput_valueœ,œidœ:œAgent-HoULPœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-nzVmM", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-nzVmMœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-HoULP", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-HoULPœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-A0PBx", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-HoULP", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "xy-edge__CalculatorComponent-A0PBx{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-A0PBxœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-HoULP{œfieldNameœ:œtoolsœ,œidœ:œAgent-HoULPœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "CalculatorComponent-A0PBx", - "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-A0PBxœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-HoULP", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-HoULPœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - } - ], "nodes": [ { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-nzVmM", + "id": "Prompt-Pe4nO", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": { @@ -106,9 +23,7 @@ "display_name": "Prompt", "documentation": "", "edited": false, - "field_order": [ - "template" - ], + "field_order": ["template"], "frozen": false, "icon": "prompts", "legacy": false, @@ -122,9 +37,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -157,10 +70,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -180,10 +90,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -203,10 +110,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -226,10 +130,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -249,10 +150,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -288,9 +186,7 @@ "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", @@ -311,10 +207,10 @@ }, "dragging": false, "height": 693, - "id": "Prompt-nzVmM", + "id": "Prompt-Pe4nO", "measured": { "height": 693, - "width": 360 + "width": 320 }, "position": { "x": 1349.861745038984, @@ -332,11 +228,9 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-60t7m", + "id": "ChatOutput-YQ7Vi", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -368,9 +262,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -383,9 +275,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -405,9 +295,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -445,9 +333,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -467,9 +353,7 @@ "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", @@ -490,10 +374,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -509,9 +390,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -531,9 +410,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -569,9 +446,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -592,10 +467,10 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-60t7m", + "id": "ChatOutput-YQ7Vi", "measured": { "height": 234, - "width": 360 + "width": 320 }, "position": { "x": 2240.3625274769397, @@ -611,7 +486,7 @@ }, { "data": { - "id": "note-BnQHz", + "id": "note-o7ebV", "node": { "description": "# SaaS Pricing Calculator\n\nWelcome to the SaaS Pricing Calculator! This flow helps you determine the optimal monthly subscription price for your software service.\n\n## Instructions\n\n1. Prepare Your Data\n - Gather information on monthly infrastructure costs\n - Calculate customer support expenses\n - Estimate continuous development costs\n - Decide on your desired profit margin\n - Determine the estimated number of subscribers\n\n2. Input Values\n - Enter the gathered data into the respective fields in the Prompt node\n - Double-check the accuracy of your inputs\n\n3. Run the Flow\n - Click the \"Run\" button to start the calculation process\n - The flow will use Chain-of-Thought prompting to guide the AI through the steps\n\n4. Review the Results\n - Examine the output in the Chat Output node\n - The result will show a breakdown of costs and the final subscription price\n\n5. Adjust and Refine\n - If needed, modify your inputs to explore different pricing scenarios\n - Re-run the flow to see how changes affect the final price\n\nRemember: Regularly update your costs and subscriber estimates to keep your pricing model accurate and competitive! 💼📊", "display_name": "", @@ -622,10 +497,10 @@ }, "dragging": false, "height": 800, - "id": "note-BnQHz", + "id": "note-o7ebV", "measured": { "height": 800, - "width": 328 + "width": 325 }, "position": { "x": 689.7659055360411, @@ -648,11 +523,9 @@ "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-HoULP", + "id": "Agent-LDhCf", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -701,9 +574,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -732,9 +603,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -783,10 +652,8 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], - "load_from_db": true, + "input_types": ["Message"], + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -836,9 +703,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -912,9 +777,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -1008,10 +871,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -1045,11 +905,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -1065,9 +921,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1087,9 +941,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1109,9 +961,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1148,9 +998,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1171,9 +1019,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -1207,10 +1053,10 @@ }, "dragging": false, "height": 650, - "id": "Agent-HoULP", + "id": "Agent-LDhCf", "measured": { "height": 650, - "width": 360 + "width": 320 }, "position": { "x": 1819.2633856623966, @@ -1226,11 +1072,9 @@ }, { "data": { - "id": "CalculatorComponent-A0PBx", + "id": "CalculatorComponent-unDLj", "node": { - "base_classes": [ - "Data" - ], + "base_classes": ["Data"], "beta": false, "category": "tools", "conditional_paths": [], @@ -1239,9 +1083,7 @@ "display_name": "Calculator", "documentation": "", "edited": false, - "field_order": [ - "expression" - ], + "field_order": ["expression"], "frozen": false, "icon": "calculator", "key": "CalculatorComponent", @@ -1251,17 +1093,15 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Toolset", - "hidden": null, - "method": "to_toolkit", - "name": "component_as_tool", - "required_inputs": null, + "types": ["Tool"], "selected": "Tool", - "types": [ - "Tool" - ], - "value": "__UNDEFINED__" + "name": "component_as_tool", + "hidden": null, + "display_name": "Toolset", + "method": "to_toolkit", + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": null } ], "pinned": false, @@ -1292,9 +1132,7 @@ "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, @@ -1310,111 +1148,96 @@ "value": "" }, "tools_metadata": { - "_input_type": "TableInput", - "advanced": false, - "display_name": "Edit tools", - "dynamic": false, - "info": "", + "tool_mode": false, "is_list": true, "list_add_label": "Add More", - "name": "tools_metadata", - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, + "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, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "hide_options": true, "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] + "name": ["snake_case", "no_blank"], + "commands": "commands" }, - "hide_options": true + "description": "Modify tool names and descriptions to help agents understand when to use each tool." }, - "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" - }, - { - "description": "Add commands to the tool. These commands will be used to run the tool. Start all commands with a `/`. You can add multiple commands separated by a comma.\nExample: `/command1`, `/command2`, `/command3`", - "disable_edit": false, - "display_name": "Commands", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "commands", - "sortable": false, - "type": "text" - } - ] - }, - "title_case": false, - "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "required": false, + "placeholder": "", + "show": true, + "name": "tools_metadata", "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 }, "showNode": true, "type": "CalculatorComponent" }, "dragging": false, - "id": "CalculatorComponent-A0PBx", + "id": "CalculatorComponent-unDLj", "measured": { - "height": 374, - "width": 360 + "height": 333, + "width": 320 }, "position": { "x": 1350.9477037257504, @@ -1424,10 +1247,79 @@ "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": -453.80822100847854, - "y": 40.05341665740133, - "zoom": 0.7636833920540887 + "x": -412.6248764419154, + "y": 239.5139629945674, + "zoom": 0.6920494987327928 } }, "description": "Calculate SaaS subscription price based on costs, profit margin, and subscribers using step-by-step method and Chain-of-Thought prompting. ", @@ -1438,8 +1330,5 @@ "is_component": false, "last_tested_version": "1.1.1", "name": "SaaS Pricing", - "tags": [ - "agents", - "assistants" - ] -} \ No newline at end of file + "tags": ["agents", "assistants"] +} 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 8d28d88f8..c7a7efbbe 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,316 +1,13 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-rPwbg", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-rH74C", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-rPwbg{œdataTypeœ:œPromptœ,œidœ:œPrompt-rPwbgœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-rH74C{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-rH74Cœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-rPwbg", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-rPwbgœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-rH74C", - "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-rH74Cœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-DGXf4", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-vIPAK", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-DGXf4{œdataTypeœ:œPromptœ,œidœ:œPrompt-DGXf4œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-vIPAK{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-vIPAKœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-DGXf4", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-DGXf4œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-vIPAK", - "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-vIPAKœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-rH74C", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-oAzS1", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-rH74C{œdataTypeœ:œAgentœ,œidœ:œAgent-rH74Cœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-oAzS1{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-oAzS1œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-rH74C", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-rH74Cœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-oAzS1", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-oAzS1œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "CalculatorTool", - "id": "CalculatorTool-xo5ux", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-rH74C", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-CalculatorTool-xo5ux{œdataTypeœ:œCalculatorToolœ,œidœ:œCalculatorTool-xo5uxœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-rH74C{œfieldNameœ:œtoolsœ,œidœ:œAgent-rH74Cœ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "CalculatorTool-xo5ux", - "sourceHandle": "{œdataTypeœ: œCalculatorToolœ, œidœ: œCalculatorTool-xo5uxœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-rH74C", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-rH74Cœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "YahooFinanceTool", - "id": "YahooFinanceTool-YmOKx", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-vIPAK", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-YahooFinanceTool-YmOKx{œdataTypeœ:œYahooFinanceToolœ,œidœ:œYahooFinanceTool-YmOKxœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-vIPAK{œfieldNameœ:œtoolsœ,œidœ:œAgent-vIPAKœ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "YahooFinanceTool-YmOKx", - "sourceHandle": "{œdataTypeœ: œYahooFinanceToolœ, œidœ: œYahooFinanceTool-YmOKxœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-vIPAK", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-vIPAKœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-vIPAK", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "finance_agent_output", - "id": "Prompt-rPwbg", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-vIPAK{œdataTypeœ:œAgentœ,œidœ:œAgent-vIPAKœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-rPwbg{œfieldNameœ:œfinance_agent_outputœ,œidœ:œPrompt-rPwbgœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-vIPAK", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-vIPAKœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-rPwbg", - "targetHandle": "{œfieldNameœ: œfinance_agent_outputœ, œidœ: œPrompt-rPwbgœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-3mEtf", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-uaR2o", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-3mEtf{œdataTypeœ:œChatInputœ,œidœ:œChatInput-3mEtfœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-uaR2o{œfieldNameœ:œinput_valueœ,œidœ:œAgent-uaR2oœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-3mEtf", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-3mEtfœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-uaR2o", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-uaR2oœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-BS8ii", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "system_prompt", - "id": "Agent-uaR2o", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-BS8ii{œdataTypeœ:œPromptœ,œidœ:œPrompt-BS8iiœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-Agent-uaR2o{œfieldNameœ:œsystem_promptœ,œidœ:œAgent-uaR2oœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-BS8ii", - "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-BS8iiœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-uaR2o", - "targetHandle": "{œfieldNameœ: œsystem_promptœ, œidœ: œAgent-uaR2oœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "TavilyAISearch", - "id": "TavilyAISearch-YfG8u", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-uaR2o", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-TavilyAISearch-YfG8u{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-YfG8uœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-uaR2o{œfieldNameœ:œtoolsœ,œidœ:œAgent-uaR2oœ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "TavilyAISearch-YfG8u", - "sourceHandle": "{œdataTypeœ: œTavilyAISearchœ, œidœ: œTavilyAISearch-YfG8uœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-uaR2o", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-uaR2oœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-uaR2o", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-vIPAK", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-uaR2o{œdataTypeœ:œAgentœ,œidœ:œAgent-uaR2oœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-vIPAK{œfieldNameœ:œinput_valueœ,œidœ:œAgent-vIPAKœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-uaR2o", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-uaR2oœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-vIPAK", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-vIPAKœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-uaR2o", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "research_agent_output", - "id": "Prompt-rPwbg", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-uaR2o{œdataTypeœ:œAgentœ,œidœ:œAgent-uaR2oœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-rPwbg{œfieldNameœ:œresearch_agent_outputœ,œidœ:œPrompt-rPwbgœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-uaR2o", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-uaR2oœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Prompt-rPwbg", - "targetHandle": "{œfieldNameœ: œresearch_agent_outputœ, œidœ: œPrompt-rPwbgœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" - } - ], "nodes": [ { "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-oAzS1", + "id": "ChatOutput-E20qD", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -342,9 +39,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -357,9 +52,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -379,9 +72,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -419,9 +110,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -441,9 +130,7 @@ "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", @@ -464,10 +151,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -483,9 +167,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -505,9 +187,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -543,9 +223,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -566,7 +244,7 @@ }, "dragging": false, "height": 234, - "id": "ChatOutput-oAzS1", + "id": "ChatOutput-E20qD", "position": { "x": 1239.222567317785, "y": -920.0283175735606 @@ -577,17 +255,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 234 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Finance Agent", - "id": "Agent-vIPAK", + "id": "Agent-opLbj", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -636,9 +316,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -667,9 +345,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -718,9 +394,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -729,7 +403,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -771,9 +445,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -847,9 +519,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -943,10 +613,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -980,11 +647,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -1000,9 +663,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1022,9 +683,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1044,9 +703,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1083,9 +740,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1106,9 +761,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -1142,7 +795,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-vIPAK", + "id": "Agent-opLbj", "position": { "x": 45.70736046026991, "y": -1369.035463408626 @@ -1153,17 +806,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 650 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Analysis & Editor Agent", - "id": "Agent-rH74C", + "id": "Agent-b9Ndr", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1212,9 +867,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1243,9 +896,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1294,9 +945,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -1305,7 +954,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -1347,9 +996,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1423,9 +1070,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -1519,10 +1164,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -1556,11 +1198,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -1576,9 +1214,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1598,9 +1234,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1620,9 +1254,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1659,9 +1291,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1682,9 +1312,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -1718,7 +1346,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-rH74C", + "id": "Agent-b9Ndr", "position": { "x": 815.1900903820148, "y": -1365.4053932711827 @@ -1729,17 +1357,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 650 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-BS8ii", + "id": "Prompt-IG0jU", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": { @@ -1750,9 +1380,7 @@ "documentation": "", "edited": false, "error": null, - "field_order": [ - "template" - ], + "field_order": ["template"], "frozen": true, "full_path": null, "icon": "prompts", @@ -1771,9 +1399,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1822,9 +1448,7 @@ "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", @@ -1845,7 +1469,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-BS8ii", + "id": "Prompt-IG0jU", "position": { "x": -1142.2312935529987, "y": -1107.442614776065 @@ -1856,17 +1480,19 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 260 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-DGXf4", + "id": "Prompt-uNyIS", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": { @@ -1877,9 +1503,7 @@ "documentation": "", "edited": false, "error": null, - "field_order": [ - "template" - ], + "field_order": ["template"], "frozen": false, "full_path": null, "icon": "prompts", @@ -1898,9 +1522,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1949,9 +1571,7 @@ "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", @@ -1972,7 +1592,7 @@ }, "dragging": false, "height": 260, - "id": "Prompt-DGXf4", + "id": "Prompt-uNyIS", "position": { "x": -344.9674638932195, "y": -1280.1782190739505 @@ -1983,33 +1603,30 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 260 + } }, { "data": { "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", - "id": "Prompt-rPwbg", + "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", @@ -2028,9 +1645,7 @@ "method": "build_prompt", "name": "prompt", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2063,10 +1678,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -2086,10 +1698,7 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": [ - "Message", - "Text" - ], + "input_types": ["Message", "Text"], "list": false, "load_from_db": false, "multiline": true, @@ -2125,9 +1734,7 @@ "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", @@ -2148,7 +1755,7 @@ }, "dragging": false, "height": 433, - "id": "Prompt-rPwbg", + "id": "Prompt-cisfj", "position": { "x": 416.02309796632085, "y": -1081.5957453651372 @@ -2159,15 +1766,17 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 433 + } }, { "data": { - "id": "ChatInput-3mEtf", + "id": "ChatInput-hE8ZA", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2199,9 +1808,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2214,9 +1821,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -2236,9 +1841,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -2341,10 +1944,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -2360,9 +1960,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -2382,9 +1980,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -2420,9 +2016,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -2443,7 +2037,7 @@ }, "dragging": false, "height": 234, - "id": "ChatInput-3mEtf", + "id": "ChatInput-hE8ZA", "position": { "x": -1510.6054210793818, "y": -947.702056394023 @@ -2454,138 +2048,202 @@ }, "selected": false, "type": "genericNode", - "width": 320 - }, - { - "data": { - "id": "CalculatorTool-xo5ux", - "node": { - "base_classes": [ - "Data", - "Tool" - ], - "beta": false, - "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", - "legacy": false, - "lf_version": "1.0.19.post2", - "metadata": {}, - "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": { - "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\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\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n name = \"CalculatorTool\"\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 # Define the allowed operators\n 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 if isinstance(node, ast.Num):\n return node.n\n if isinstance(node, ast.BinOp):\n return operators[type(node.op)](self._eval_expr(node.left), self._eval_expr(node.right))\n if isinstance(node, ast.UnaryOp):\n return operators[type(node.op)](self._eval_expr(node.operand))\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" - }, - "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, - "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": "" - } - }, - "tool_mode": false - }, - "type": "CalculatorTool" - }, - "dragging": false, - "height": 254, - "id": "CalculatorTool-xo5ux", - "position": { - "x": 415.51528601650625, - "y": -603.8178818852236 - }, - "positionAbsolute": { - "x": 415.51528601650625, - "y": -603.8178818852236 - }, - "selected": false, - "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 234 + } }, { "data": { "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", - "display_name": "Tavily AI Search", - "id": "TavilyAISearch-YfG8u", + "display_name": "Tavily AI Search [DEPRECATED]", + "id": "TavilyAISearch-KZP5i", "node": { - "base_classes": [ - "Data", - "Tool" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, + "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 + } + }, "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", - "display_name": "Tavily AI Search", + "icon": "TavilyIcon", + "base_classes": ["Data", "Tool"], + "display_name": "Tavily AI Search [DEPRECATED]", "documentation": "https://docs.tavily.com/", - "edited": false, + "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"] + } + ], "field_order": [ "api_key", "query", @@ -2595,204 +2253,17 @@ "include_images", "include_answer" ], - "frozen": false, - "icon": "TavilyIcon", - "legacy": false, - "lf_version": "1.0.19.post2", + "beta": false, + "legacy": true, + "edited": false, "metadata": {}, - "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\"\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\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, - "name": "include_answer", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "include_images", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "max_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "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" }, "dragging": false, "height": 394, - "id": "TavilyAISearch-YfG8u", + "id": "TavilyAISearch-KZP5i", "position": { "x": -1132.8634419233736, "y": -770.0391255413992 @@ -2803,11 +2274,15 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 394 + } }, { "data": { - "id": "note-8beLl", + "id": "note-e59F1", "node": { "description": "# Sequential Tasks Agents\n\n## Overview\nThis flow demonstrates how to chain multiple AI agents for comprehensive research and analysis. Each agent specializes in different aspects of the research process, building upon the previous agent's work.\n\n## How to Use the Flow\n\n1. **Input Your Query** 🎯\n - Be specific and clear\n - Include key aspects you want analyzed\n - Examples:\n ```\n Good: \"Should I invest in Tesla (TSLA)? Focus on AI development impact\"\n Bad: \"Tell me about Tesla\"\n ```\n\n2. **Research Agent Process** 🔍\n - Utilizes Tavily Search for comprehensive research\n\n\n3. **Specialized Analysis** 📊\n - Each agent adds unique value:\n ```\n Research Agent → Deep Research & Context\n ↓\n Finance Agent → Data Analysis & Metrics\n ↓\n Editor Agent → Final Synthesis & Report\n ```\n\n4. **Output Format** 📝\n - Structured report\n - Embedded images and charts\n - Data-backed insights\n - Clear recommendations\n\n## Pro Tips\n\n### Query Construction\n- Include specific points of interest\n- Mention required metrics or data points\n- Specify time frames if relevant\n\n### Flow Customization\n- Modify agent prompts for different use cases\n- Add or remove tools as needed\n\n## Common Applications\n- Investment Research\n- Market Analysis\n- Competitive Intelligence\n- Industry Reports\n- Technology Impact Studies\n\n⚡ **Best Practice**: Start with a test query to understand the flow's capabilities before running complex analyses.\n\n---\n*Note: This flow template uses financial analysis as an example but can be adapted for any research-intensive task requiring multiple perspectives and data sources.*", "display_name": "", @@ -2818,7 +2293,7 @@ }, "dragging": false, "height": 800, - "id": "note-8beLl", + "id": "note-e59F1", "position": { "x": -2122.739127560837, "y": -1302.6582482086806 @@ -2834,11 +2309,15 @@ "width": 600 }, "type": "noteNode", - "width": 600 + "width": 600, + "measured": { + "width": 325, + "height": 800 + } }, { "data": { - "id": "note-tB2J2", + "id": "note-7HeUD", "node": { "description": "## What Are Sequential Task Agents?\nA system where multiple AI agents work in sequence, each specializing in specific tasks and passing their output to the next agent in the chain. Think of it as an assembly line where each agent adds value to the final result.\n\n## How It Works\n1. **First Agent** → **Second Agent** → **Third Agent** → **Final Output**\n - Each agent receives input from the previous one\n - Processes and enhances the information\n - Passes refined output forward\n\n## Key Benefits\n- **Specialization**: Each agent focuses on specific tasks\n- **Progressive Refinement**: Information gets enhanced at each step\n- **Structured Output**: Final result combines multiple perspectives\n- **Quality Control**: Each agent validates and improves previous work\n\n## Building Your Own Sequence\n1. **Plan Your Chain**\n - Identify distinct tasks\n - Determine logical order\n - Define input/output requirements\n\n2. **Configure Agents**\n - Give each agent clear instructions\n - Ensure compatible outputs/inputs\n - Set appropriate tools for each agent\n\n3. **Connect the Flow**\n - Link agents in proper order\n - Test data flow between agents\n - Verify final output format\n\n## Example Applications\n- Research → Analysis → Report Writing\n- Data Collection → Processing → Visualization\n- Content Research → Writing → Editing\n- Market Analysis → Financial Review → Investment Advice\n\n⭐ **Pro Tip**: The strength of sequential agents comes from how well they complement each other's capabilities.\n\nThis template uses financial analysis as an example, but you can adapt it for any multi-step process requiring different expertise at each stage.", "display_name": "", @@ -2851,7 +2330,7 @@ }, "dragging": false, "height": 800, - "id": "note-tB2J2", + "id": "note-7HeUD", "position": { "x": -1456.0688717707517, "y": -1916.6876704866322 @@ -2867,192 +2346,19 @@ "width": 600 }, "type": "noteNode", - "width": 600 - }, - { - "data": { - "id": "YahooFinanceTool-YmOKx", - "node": { - "base_classes": [ - "Data", - "Tool" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, - "description": "Access financial data and market information using Yahoo Finance.", - "display_name": "Yahoo Finance", - "documentation": "", - "edited": false, - "field_order": [ - "symbol", - "method", - "num_news" - ], - "frozen": false, - "icon": "trending-up", - "legacy": false, - "lf_version": "1.0.19.post2", - "metadata": {}, - "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": { - "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 pprint\nfrom enum import Enum\n\nimport yfinance as yf\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 DropdownInput, IntInput, MessageTextInput\nfrom langflow.schema import Data\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 YfinanceToolComponent(LCToolComponent):\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 name = \"YahooFinanceTool\"\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 ),\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 def run_model(self) -> list[Data]:\n return self._yahoo_finance_tool(\n self.symbol,\n self.method,\n self.num_news,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"yahoo_finance\",\n description=\"Access financial data and market information from Yahoo Finance.\",\n func=self._yahoo_finance_tool,\n args_schema=YahooFinanceSchema,\n )\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\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\n result = pprint.pformat(result)\n\n if method == YahooFinanceMethod.GET_NEWS:\n data_list = [Data(data=article) for article in ast.literal_eval(result)]\n else:\n data_list = [Data(data={\"result\": result})]\n\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 return data_list\n" - }, - "method": { - "_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", - "get_actions", - "get_analysis", - "get_balance_sheet", - "get_calendar", - "get_cashflow", - "get_institutional_holders", - "get_recommendations", - "get_sustainability", - "get_major_holders", - "get_mutualfund_holders", - "get_insider_purchases", - "get_insider_transactions", - "get_insider_roster_holders", - "get_dividends", - "get_capital_gains", - "get_splits", - "get_shares", - "get_fast_info", - "get_sec_filings", - "get_recommendations_summary", - "get_upgrades_downgrades", - "get_earnings", - "get_income_stmt" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_metadata": true, - "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, - "name": "num_news", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_metadata": true, - "type": "int", - "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, - "load_from_db": false, - "name": "symbol", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "tool_mode": false, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "AAPL" - } - }, - "tool_mode": false - }, - "type": "YahooFinanceTool" - }, - "dragging": false, - "height": 475, - "id": "YahooFinanceTool-YmOKx", - "position": { - "x": -338.2658218008318, - "y": -945.7435123503128 - }, - "positionAbsolute": { - "x": -338.2658218008318, - "y": -945.7435123503128 - }, - "selected": false, - "type": "genericNode", - "width": 320 + "width": 600, + "measured": { + "width": 325, + "height": 800 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Researcher Agent", - "id": "Agent-uaR2o", + "id": "Agent-AngMf", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -3101,9 +2407,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -3132,9 +2436,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -3183,9 +2485,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": true, "name": "api_key", "password": true, @@ -3194,7 +2494,7 @@ "show": true, "title_case": false, "type": "str", - "value": "OPENAI_API_KEY" + "value": "" }, "code": { "advanced": true, @@ -3236,9 +2536,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -3312,9 +2610,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -3408,10 +2704,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -3445,11 +2738,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -3465,9 +2754,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -3487,9 +2774,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -3509,9 +2794,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -3548,9 +2831,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -3571,9 +2852,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -3607,7 +2886,7 @@ }, "dragging": false, "height": 650, - "id": "Agent-uaR2o", + "id": "Agent-AngMf", "position": { "x": -715.1798010873374, "y": -1342.256094001045 @@ -3618,11 +2897,15 @@ }, "selected": false, "type": "genericNode", - "width": 320 + "width": 320, + "measured": { + "width": 320, + "height": 650 + } }, { "data": { - "id": "note-9ZCze", + "id": "note-RNWTM", "node": { "description": "## Get your API key at [https://tavily.com](https://tavily.com)\n", "display_name": "", @@ -3635,7 +2918,7 @@ }, "dragging": false, "height": 324, - "id": "note-9ZCze", + "id": "note-RNWTM", "position": { "x": -1144.3898055225054, "y": -844.3506743985376 @@ -3651,11 +2934,15 @@ "width": 347 }, "type": "noteNode", - "width": 347 + "width": 347, + "measured": { + "width": 325, + "height": 324 + } }, { "data": { - "id": "note-ynS9s", + "id": "note-Rv3Gc", "node": { "description": "## Configure the agent by obtaining your OpenAI API key from [platform.openai.com](https://platform.openai.com). Under \"Model Provider\", choose:\n- OpenAI: Default, requires only API key\n- Anthropic/Azure/Groq/NVIDIA: Each requires their own API keys\n- Custom: Use your own model endpoint + authentication\n\nSelect model and input API key before running the flow.", "display_name": "", @@ -3668,7 +2955,7 @@ }, "dragging": false, "height": 324, - "id": "note-ynS9s", + "id": "note-Rv3Gc", "position": { "x": -739.4383746675942, "y": -1672.0874594411662 @@ -3684,13 +2971,687 @@ "width": 370 }, "type": "noteNode", - "width": 370 + "width": 370, + "measured": { + "width": 325, + "height": 324 + } + }, + { + "id": "YfinanceComponent-gHp4w", + "type": "genericNode", + "position": { + "x": -347.05382068428014, + "y": -950.8279673971418 + }, + "data": { + "node": { + "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, + "info": "", + "load_from_db": false, + "title_case": false + }, + "method": { + "tool_mode": false, + "trace_as_metadata": true, + "options": [ + "get_info", + "get_news", + "get_actions", + "get_analysis", + "get_balance_sheet", + "get_calendar", + "get_cashflow", + "get_institutional_holders", + "get_recommendations", + "get_sustainability", + "get_major_holders", + "get_mutualfund_holders", + "get_insider_purchases", + "get_insider_transactions", + "get_insider_roster_holders", + "get_dividends", + "get_capital_gains", + "get_splits", + "get_shares", + "get_fast_info", + "get_sec_filings", + "get_recommendations_summary", + "get_upgrades_downgrades", + "get_earnings", + "get_income_stmt" + ], + "combobox": false, + "required": false, + "placeholder": "", + "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", + "advanced": false, + "dynamic": false, + "info": "The number of news articles to retrieve (only applicable for get_news).", + "title_case": false, + "type": "int", + "_input_type": "IntInput" + }, + "symbol": { + "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" + }, + "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": "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_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"] + } + ], + "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 + }, + "showNode": true, + "type": "YfinanceComponent", + "id": "YfinanceComponent-gHp4w" + }, + "selected": true, + "measured": { + "width": 320, + "height": 517 + }, + "dragging": true + }, + { + "id": "CalculatorComponent-ZUJg0", + "type": "genericNode", + "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œ}" } ], "viewport": { - "x": 988.287937756906, - "y": 1011.1045224025538, - "zoom": 0.5418943314819052 + "x": 686.0720439459279, + "y": 1171.2612829417405, + "zoom": 0.6863456377538562 } }, "description": "This Agent is designed to systematically execute a series of tasks following a meticulously predefined sequence. By adhering to this structured order, the Agent ensures that each task is completed efficiently and effectively, optimizing overall performance and maintaining a high level of accuracy.", @@ -3701,9 +3662,5 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Sequential Tasks Agents", - "tags": [ - "assistants", - "agents", - "web-scraping" - ] -} \ No newline at end of file + "tags": ["assistants", "agents", "web-scraping"] +} 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 da4f4e2a0..4171ca46b 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,125 +1,13 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-8EW83", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-uEPyl", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-8EW83{œdataTypeœ:œChatInputœ,œidœ:œChatInput-8EW83œ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-uEPyl{œfieldNameœ:œinput_valueœ,œidœ:œAgent-uEPylœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-8EW83", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-8EW83œ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-uEPyl", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-uEPylœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-uEPyl", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-kqJTj", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-uEPyl{œdataTypeœ:œAgentœ,œidœ:œAgent-uEPylœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-kqJTj{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-kqJTjœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Agent-uEPyl", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-uEPylœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-kqJTj", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-kqJTjœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "URL", - "id": "URL-4LKaN", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-uEPyl", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-URL-4LKaN{œdataTypeœ:œURLœ,œidœ:œURL-4LKaNœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-uEPyl{œfieldNameœ:œtoolsœ,œidœ:œAgent-uEPylœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "URL-4LKaN", - "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-4LKaNœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-uEPyl", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-uEPylœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "data": { - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-AIdo5", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-uEPyl", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "xy-edge__CalculatorComponent-AIdo5{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-AIdo5œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-uEPyl{œfieldNameœ:œtoolsœ,œidœ:œAgent-uEPylœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "source": "CalculatorComponent-AIdo5", - "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-AIdo5œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-uEPyl", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-uEPylœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - } - ], "nodes": [ { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Agent", - "id": "Agent-uEPyl", + "id": "Agent-BStBJ", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -168,9 +56,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -199,9 +85,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -250,9 +134,7 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "load_from_db": false, "name": "api_key", "password": true, @@ -303,9 +185,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -379,9 +259,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -475,10 +353,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -512,11 +387,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -532,9 +403,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -554,9 +423,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -576,9 +443,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -615,9 +480,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -638,9 +501,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -673,9 +534,9 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-uEPyl", + "id": "Agent-BStBJ", "measured": { - "height": 624, + "height": 621, "width": 320 }, "position": { @@ -687,11 +548,9 @@ }, { "data": { - "id": "ChatInput-8EW83", + "id": "ChatInput-Hr2If", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -723,9 +582,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -738,9 +595,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -760,9 +615,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -865,10 +718,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -884,9 +734,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -906,9 +754,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -944,9 +790,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -966,9 +810,9 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-8EW83", + "id": "ChatInput-Hr2If", "measured": { - "height": 230, + "height": 229, "width": 320 }, "position": { @@ -982,11 +826,9 @@ "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-kqJTj", + "id": "ChatOutput-c2K0x", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1018,9 +860,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1033,9 +873,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -1055,9 +893,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -1095,9 +931,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -1117,9 +951,7 @@ "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", @@ -1140,10 +972,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -1159,9 +988,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1181,9 +1008,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1219,9 +1044,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -1240,9 +1063,9 @@ }, "type": "ChatOutput" }, - "id": "ChatOutput-kqJTj", + "id": "ChatOutput-c2K0x", "measured": { - "height": 230, + "height": 229, "width": 320 }, "position": { @@ -1256,242 +1079,207 @@ "data": { "description": "Load and retrive data from specified URLs.", "display_name": "URL", - "id": "URL-4LKaN", + "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, - "lf_version": "1.1.1", - "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": { - "advanced": true, - "dynamic": true, + "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": "", - "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 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=\"Text\", 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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "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.", - "name": "format", - "options": [ - "Text", - "Raw HTML" - ], - "placeholder": "", - "required": false, - "show": true, - "title_case": false, "tool_mode": false, "trace_as_metadata": true, - "type": "str", - "value": "Text" - }, - "tools_metadata": { - "_input_type": "TableInput", + "options": ["Text", "Raw HTML"], + "combobox": false, + "required": false, + "placeholder": "", + "show": true, + "name": "format", + "value": "Text", + "display_name": "Output Format", "advanced": false, - "display_name": "Edit tools", + "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", + "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, + "type": "str", + "_input_type": "MessageTextInput" + }, + "tools_metadata": { + "tool_mode": false, "is_list": true, "list_add_label": "Add More", - "name": "tools_metadata", - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, + "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, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "hide_options": true, "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] + "name": ["snake_case", "no_blank"], + "commands": "commands" }, - "hide_options": true + "description": "Modify tool names and descriptions to help agents understand when to use each tool." }, - "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" - }, - { - "description": "Add commands to the tool. These commands will be used to run the tool. Start all commands with a `/`. You can add multiple commands separated by a comma.\nExample: `/command1`, `/command2`, `/command3`", - "disable_edit": false, - "display_name": "Commands", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "commands", - "sortable": false, - "type": "text" - } - ] - }, - "title_case": false, - "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "required": false, + "placeholder": "", + "show": true, + "name": "tools_metadata", "value": [ { - "description": "fetch_content() - Load and retrive data from specified URLs.", "name": "URL-fetch_content", - "tags": [ - "URL-fetch_content" - ] + "description": "fetch_content() - Load and retrive data from specified URLs.", + "tags": ["URL-fetch_content"] }, { - "description": "fetch_content_text() - Load and retrive data from specified URLs.", "name": "URL-fetch_content_text", - "tags": [ - "URL-fetch_content_text" - ] + "description": "fetch_content_text() - Load and retrive data from specified URLs.", + "tags": ["URL-fetch_content_text"] }, { - "description": "as_dataframe() - Load and retrive data from specified URLs.", "name": "URL-as_dataframe", - "tags": [ - "URL-as_dataframe" - ] + "description": "as_dataframe() - Load and retrive data from specified URLs.", + "tags": ["URL-as_dataframe"] } - ] - }, - "urls": { - "_input_type": "MessageTextInput", + ], + "display_name": "Edit tools", "advanced": false, - "display_name": "URLs", "dynamic": false, "info": "", - "input_types": [ - "Message" - ], - "list": true, - "list_add_label": "Add URL", - "load_from_db": false, - "name": "urls", - "placeholder": "Enter a URL...", - "required": false, - "show": true, + "real_time_refresh": true, "title_case": false, - "tool_mode": true, - "trace_as_input": true, - "trace_as_metadata": true, - "type": "str", - "value": "" + "type": "table", + "_input_type": "TableInput" } }, + "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" }, "dragging": false, - "id": "URL-4LKaN", + "id": "URL-Cns6P", "measured": { - "height": 405, + "height": 403, "width": 320 }, "position": { "x": 1225.8773509111968, "y": 27.333577318641687 }, - "selected": false, + "selected": true, "type": "genericNode" }, { "data": { - "id": "note-eGYiL", + "id": "note-gIi2r", "node": { "description": "# 📖 README\nRun an Agent with URL and Calculator tools available for its use. \nThe Agent decides which tool to use to solve a problem.\n## Quick start\n\n1. Add your OpenAI API key to the Agent.\n2. Open the Playground and chat with the Agent. Request some information about a recipe, and then ask to add two numbers together. In the responses, the Agent will use different tools to solve different problems.\n\n## Next steps\nConnect more tools to the Agent to create your perfect assistant.\n\nFor more, see the [Langflow docs](https://docs.langflow.org/agents-tool-calling-agent-component).", "display_name": "", @@ -1503,7 +1291,7 @@ "type": "note" }, "dragging": false, - "id": "note-eGYiL", + "id": "note-gIi2r", "measured": { "height": 325, "width": 325 @@ -1512,12 +1300,12 @@ "x": 775.5268622081468, "y": 27.927425537464444 }, - "selected": true, + "selected": false, "type": "noteNode" }, { "data": { - "id": "note-yaAhu", + "id": "note-E1ls9", "node": { "description": "### 💡 Add your OpenAI API key here👇", "display_name": "", @@ -1528,7 +1316,7 @@ }, "type": "note" }, - "id": "note-yaAhu", + "id": "note-E1ls9", "measured": { "height": 324, "width": 324 @@ -1542,11 +1330,9 @@ }, { "data": { - "id": "CalculatorComponent-AIdo5", + "id": "CalculatorComponent-RGZ02", "node": { - "base_classes": [ - "Data" - ], + "base_classes": ["Data"], "beta": false, "category": "tools", "conditional_paths": [], @@ -1555,9 +1341,7 @@ "display_name": "Calculator", "documentation": "", "edited": false, - "field_order": [ - "expression" - ], + "field_order": ["expression"], "frozen": false, "icon": "calculator", "key": "CalculatorComponent", @@ -1568,17 +1352,15 @@ "output_types": [], "outputs": [ { - "cache": true, - "display_name": "Toolset", - "hidden": null, - "method": "to_toolkit", - "name": "component_as_tool", - "required_inputs": null, + "types": ["Tool"], "selected": "Tool", - "types": [ - "Tool" - ], - "value": "__UNDEFINED__" + "name": "component_as_tool", + "hidden": null, + "display_name": "Toolset", + "method": "to_toolkit", + "value": "__UNDEFINED__", + "cache": true, + "required_inputs": null } ], "pinned": false, @@ -1609,9 +1391,7 @@ "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, @@ -1627,100 +1407,84 @@ "value": "" }, "tools_metadata": { - "_input_type": "TableInput", - "advanced": false, - "display_name": "Edit tools", - "dynamic": false, - "info": "", + "tool_mode": false, "is_list": true, "list_add_label": "Add More", - "name": "tools_metadata", - "placeholder": "", - "real_time_refresh": true, - "required": false, - "show": true, + "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, - "block_sort": true, - "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "hide_options": true, "field_parsers": { - "commands": "commands", - "name": [ - "snake_case", - "no_blank" - ] + "name": ["snake_case", "no_blank"], + "commands": "commands" }, - "hide_options": true + "description": "Modify tool names and descriptions to help agents understand when to use each tool." }, - "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" - }, - { - "description": "Add commands to the tool. These commands will be used to run the tool. Start all commands with a `/`. You can add multiple commands separated by a comma.\nExample: `/command1`, `/command2`, `/command3`", - "disable_edit": false, - "display_name": "Commands", - "edit_mode": "inline", - "filterable": false, - "formatter": "text", - "name": "commands", - "sortable": false, - "type": "text" - } - ] - }, - "title_case": false, - "tool_mode": false, "trace_as_metadata": true, - "trigger_icon": "Hammer", - "trigger_text": "", - "type": "table", + "required": false, + "placeholder": "", + "show": true, + "name": "tools_metadata", "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 @@ -1729,9 +1493,9 @@ "type": "CalculatorComponent" }, "dragging": false, - "id": "CalculatorComponent-AIdo5", + "id": "CalculatorComponent-RGZ02", "measured": { - "height": 334, + "height": 333, "width": 320 }, "position": { @@ -1742,10 +1506,82 @@ "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": -448.3479511888586, - "y": 46.99841717123451, - "zoom": 0.7790395954652126 + "x": -573.0285266811966, + "y": 96.72381189311284, + "zoom": 0.8223516559988604 } }, "description": "A simple but powerful starter agent.", @@ -1754,8 +1590,5 @@ "is_component": false, "last_tested_version": "1.1.1", "name": "Simple Agent", - "tags": [ - "assistants", - "agents" - ] -} \ No newline at end of file + "tags": ["assistants", "agents"] +} 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 9b7f0a6ea..a8da3a34a 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,204 +1,11 @@ { "data": { - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-LAoR7", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-EXlcd", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-LAoR7{œdataTypeœ:œAgentœ,œidœ:œAgent-LAoR7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-EXlcd{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-EXlcdœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-LAoR7", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-LAoR7œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "ChatOutput-EXlcd", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-EXlcdœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-qPNh7", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-LAoR7", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-qPNh7{œdataTypeœ:œAgentœ,œidœ:œAgent-qPNh7œ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-LAoR7{œfieldNameœ:œinput_valueœ,œidœ:œAgent-LAoR7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-qPNh7", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-qPNh7œ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-LAoR7", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-LAoR7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-uVWaZ", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-qPNh7", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-uVWaZ{œdataTypeœ:œAgentœ,œidœ:œAgent-uVWaZœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Agent-qPNh7{œfieldNameœ:œinput_valueœ,œidœ:œAgent-qPNh7œ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Agent-uVWaZ", - "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-uVWaZœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-qPNh7", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-qPNh7œ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "SearchAPI", - "id": "SearchAPI-zMZv7", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-uVWaZ", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-SearchAPI-zMZv7{œdataTypeœ:œSearchAPIœ,œidœ:œSearchAPI-zMZv7œ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-uVWaZ{œfieldNameœ:œtoolsœ,œidœ:œAgent-uVWaZœ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "SearchAPI-zMZv7", - "sourceHandle": "{œdataTypeœ: œSearchAPIœ, œidœ: œSearchAPI-zMZv7œ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-uVWaZ", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-uVWaZœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "url_content_fetcher", - "id": "url_content_fetcher-p0SUP", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-qPNh7", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-url_content_fetcher-p0SUP{œdataTypeœ:œurl_content_fetcherœ,œidœ:œurl_content_fetcher-p0SUPœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-qPNh7{œfieldNameœ:œtoolsœ,œidœ:œAgent-qPNh7œ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "url_content_fetcher-p0SUP", - "sourceHandle": "{œdataTypeœ: œurl_content_fetcherœ, œidœ: œurl_content_fetcher-p0SUPœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-qPNh7", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-qPNh7œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "CalculatorTool", - "id": "CalculatorTool-v71XZ", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-LAoR7", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-CalculatorTool-v71XZ{œdataTypeœ:œCalculatorToolœ,œidœ:œCalculatorTool-v71XZœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-LAoR7{œfieldNameœ:œtoolsœ,œidœ:œAgent-LAoR7œ,œinputTypesœ:[œToolœ,œBaseToolœ,œStructuredToolœ],œtypeœ:œotherœ}", - "source": "CalculatorTool-v71XZ", - "sourceHandle": "{œdataTypeœ: œCalculatorToolœ, œidœ: œCalculatorTool-v71XZœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-LAoR7", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-LAoR7œ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-iWWoE", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-uVWaZ", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-iWWoE{œdataTypeœ:œChatInputœ,œidœ:œChatInput-iWWoEœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-uVWaZ{œfieldNameœ:œinput_valueœ,œidœ:œAgent-uVWaZœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-iWWoE", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-iWWoEœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-uVWaZ", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-uVWaZœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" - } - ], "nodes": [ { "data": { - "id": "ChatInput-iWWoE", + "id": "ChatInput-onw3j", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -227,9 +34,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -242,9 +47,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -263,9 +66,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -366,10 +167,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -384,9 +182,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -405,9 +201,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -442,9 +236,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -463,7 +255,7 @@ }, "dragging": false, "height": 262, - "id": "ChatInput-iWWoE", + "id": "ChatInput-onw3j", "position": { "x": 1756.77096149088, "y": 292.73476765276695 @@ -472,19 +264,21 @@ "x": 1756.77096149088, "y": 292.73476765276695 }, - "selected": true, + "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 262 + } }, { "data": { "description": "Display a chat message in the Playground.", "display_name": "Chat Output", - "id": "ChatOutput-EXlcd", + "id": "ChatOutput-UWiDB", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -516,9 +310,7 @@ "method": "message_response", "name": "message", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -531,9 +323,7 @@ "display_name": "Background Color", "dynamic": false, "info": "The background color of the icon.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "background_color", @@ -553,9 +343,7 @@ "display_name": "Icon", "dynamic": false, "info": "The icon of the message.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "chat_icon", @@ -593,9 +381,7 @@ "display_name": "Data Template", "dynamic": false, "info": "Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "data_template", @@ -615,9 +401,7 @@ "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", @@ -638,10 +422,7 @@ "dynamic": false, "info": "Type of sender.", "name": "sender", - "options": [ - "Machine", - "User" - ], + "options": ["Machine", "User"], "placeholder": "", "required": false, "show": true, @@ -657,9 +438,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Name of the sender.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -679,9 +458,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -717,9 +494,7 @@ "display_name": "Text Color", "dynamic": false, "info": "The text color of the name", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "text_color", @@ -740,7 +515,7 @@ }, "dragging": false, "height": 262, - "id": "ChatOutput-EXlcd", + "id": "ChatOutput-UWiDB", "position": { "x": 4349.229697347143, "y": 620.5490494265098 @@ -751,23 +526,184 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 262 + } }, { "data": { - "id": "SearchAPI-zMZv7", + "id": "SearchAPI-KMYDO", "node": { - "base_classes": [ - "Data", - "Tool" - ], - "beta": false, - "conditional_paths": [], - "custom_fields": {}, + "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" + } + }, "description": "Call the searchapi.io API with result limiting", - "display_name": "Search API", + "icon": "SearchAPI", + "base_classes": ["Data", "Tool"], + "display_name": "Search API [DEPRECATED]", "documentation": "https://www.searchapi.io/docs/google", - "edited": false, + "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"] + } + ], "field_order": [ "engine", "api_key", @@ -776,182 +712,19 @@ "max_results", "max_snippet_length" ], - "frozen": false, - "icon": "SearchAPI", - "legacy": false, + "beta": false, + "legacy": true, + "edited": false, "metadata": {}, - "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\"\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\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, - "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, - "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, - "name": "max_results", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "max_snippet_length", - "placeholder": "", - "required": false, - "show": true, - "title_case": 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, - "name": "search_params", - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "trace_as_input": true, - "type": "dict", - "value": {} - } - }, "tool_mode": false }, - "type": "SearchAPI" + "type": "SearchAPI", + "description": "Call the searchapi.io API with result limiting", + "display_name": "Search API [DEPRECATED]" }, "dragging": false, "height": 509, - "id": "SearchAPI-zMZv7", + "id": "SearchAPI-KMYDO", "position": { "x": 2101.519951743063, "y": 949.7032293566349 @@ -962,17 +735,17 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 509 + } }, { "data": { - "id": "url_content_fetcher-p0SUP", + "id": "url_content_fetcher-vZFfk", "node": { - "base_classes": [ - "Data", - "list", - "Tool" - ], + "base_classes": ["Data", "list", "Tool"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -980,10 +753,7 @@ "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", @@ -997,10 +767,7 @@ "method": "run_model", "name": "api_run_model", "selected": "Data", - "types": [ - "Data", - "list" - ], + "types": ["Data", "list"], "value": "__UNDEFINED__" }, { @@ -1009,9 +776,7 @@ "method": "build_tool", "name": "api_build_tool", "selected": "Tool", - "types": [ - "Tool" - ], + "types": ["Tool"], "value": "__UNDEFINED__" } ], @@ -1058,9 +823,7 @@ "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", @@ -1079,7 +842,7 @@ }, "dragging": false, "height": 262, - "id": "url_content_fetcher-p0SUP", + "id": "url_content_fetcher-vZFfk", "position": { "x": 2834.525991812012, "y": 939.6518333549263 @@ -1090,110 +853,105 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 262 + } }, { "data": { - "id": "CalculatorTool-v71XZ", + "id": "CalculatorTool-LJZFv", "node": { - "base_classes": [ - "Data", - "list", - "Sequence", - "Tool" - ], - "beta": false, - "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", - "legacy": false, - "lf_version": "1.0.19.post2", - "metadata": {}, - "official": 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": { - "advanced": true, - "dynamic": true, + "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": "", - "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\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\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n name = \"CalculatorTool\"\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 # Define the allowed operators\n 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 if isinstance(node, ast.Num):\n return node.n\n if isinstance(node, ast.BinOp):\n return operators[type(node.op)](self._eval_expr(node.left), self._eval_expr(node.right))\n if isinstance(node, ast.UnaryOp):\n return operators[type(node.op)](self._eval_expr(node.operand))\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" + "name": "code", + "advanced": true, + "dynamic": true, + "info": "", + "load_from_db": false, + "title_case": false }, "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, - "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", - "value": "2+2" + "_input_type": "MessageTextInput" } - } + }, + "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" + "type": "CalculatorTool", + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator [DEPRECATED]" }, "dragging": false, "height": 338, - "id": "CalculatorTool-v71XZ", + "id": "CalculatorTool-LJZFv", "position": { "x": 3546.599894399727, "y": 972.1522299506486 @@ -1202,19 +960,21 @@ "x": 3546.599894399727, "y": 972.1522299506486 }, - "selected": false, + "selected": true, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 338 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "City Selection Agent", - "id": "Agent-uVWaZ", + "id": "Agent-ZZ1QV", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1263,9 +1023,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1294,9 +1052,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1345,10 +1101,8 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], - "load_from_db": true, + "input_types": ["Message"], + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -1398,9 +1152,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -1474,9 +1226,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -1570,10 +1320,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -1607,11 +1354,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -1627,9 +1370,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -1649,9 +1390,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -1671,9 +1410,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1710,9 +1447,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1733,9 +1468,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -1769,7 +1502,7 @@ }, "dragging": true, "height": 725, - "id": "Agent-uVWaZ", + "id": "Agent-ZZ1QV", "position": { "x": 2472.7748760933105, "y": 335.66187210240537 @@ -1780,17 +1513,19 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 725 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Local Expert Agent", - "id": "Agent-qPNh7", + "id": "Agent-ArtN4", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -1839,9 +1574,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -1870,9 +1603,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -1921,10 +1652,8 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], - "load_from_db": true, + "input_types": ["Message"], + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -1974,9 +1703,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -2050,9 +1777,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -2146,10 +1871,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -2183,11 +1905,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -2203,9 +1921,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -2225,9 +1941,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -2247,9 +1961,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2286,9 +1998,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2309,9 +2019,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -2345,7 +2053,7 @@ }, "dragging": false, "height": 725, - "id": "Agent-qPNh7", + "id": "Agent-ArtN4", "position": { "x": 3185.66991544494, "y": 355.95841004876377 @@ -2356,17 +2064,19 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 725 + } }, { "data": { "description": "Define the agent's instructions, then enter a task to complete using tools.", "display_name": "Travel Concierge Agent", - "id": "Agent-LAoR7", + "id": "Agent-AiQA7", "node": { - "base_classes": [ - "Message" - ], + "base_classes": ["Message"], "beta": false, "conditional_paths": [], "custom_fields": {}, @@ -2415,9 +2125,7 @@ "method": "message_response", "name": "response", "selected": "Message", - "types": [ - "Message" - ], + "types": ["Message"], "value": "__UNDEFINED__" } ], @@ -2446,9 +2154,7 @@ "display_name": "Agent Description [Deprecated]", "dynamic": false, "info": "The description of the agent. This is only used when in Tool Mode. Defaults to 'A helpful assistant with access to the following tools:' and tools are added dynamically. This feature is deprecated and will be removed in future versions.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2497,10 +2203,8 @@ "display_name": "OpenAI API Key", "dynamic": false, "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Message" - ], - "load_from_db": true, + "input_types": ["Message"], + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -2550,9 +2254,7 @@ "display_name": "Input", "dynamic": false, "info": "The input provided by the user for the agent to process.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "input_value", @@ -2626,9 +2328,7 @@ "display_name": "External Memory", "dynamic": false, "info": "Retrieve messages from an external memory. If empty, it will use the Langflow tables.", - "input_types": [ - "Memory" - ], + "input_types": ["Memory"], "list": false, "name": "memory", "placeholder": "", @@ -2722,10 +2422,7 @@ "dynamic": false, "info": "Order of the messages.", "name": "order", - "options": [ - "Ascending", - "Descending" - ], + "options": ["Ascending", "Descending"], "placeholder": "", "required": false, "show": true, @@ -2759,11 +2456,7 @@ "dynamic": false, "info": "Filter by sender type.", "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], + "options": ["Machine", "User", "Machine and User"], "placeholder": "", "required": false, "show": true, @@ -2779,9 +2472,7 @@ "display_name": "Sender Name", "dynamic": false, "info": "Filter by sender name.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "sender_name", @@ -2801,9 +2492,7 @@ "display_name": "Session ID", "dynamic": false, "info": "The session ID of the chat. If empty, the current session ID parameter will be used.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "name": "session_id", @@ -2823,9 +2512,7 @@ "display_name": "Agent Instructions", "dynamic": false, "info": "System Prompt: Initial instructions and context provided to guide the agent's behavior.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2862,9 +2549,7 @@ "display_name": "Template", "dynamic": false, "info": "The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.", - "input_types": [ - "Message" - ], + "input_types": ["Message"], "list": false, "load_from_db": false, "multiline": true, @@ -2885,9 +2570,7 @@ "display_name": "Tools", "dynamic": false, "info": "These are the tools that the agent can use to help with tasks.", - "input_types": [ - "Tool" - ], + "input_types": ["Tool"], "list": true, "name": "tools", "placeholder": "", @@ -2921,7 +2604,7 @@ }, "dragging": false, "height": 725, - "id": "Agent-LAoR7", + "id": "Agent-AiQA7", "position": { "x": 3889.695953842898, "y": 370.3161168611889 @@ -2932,11 +2615,15 @@ }, "selected": false, "type": "genericNode", - "width": 360 + "width": 360, + "measured": { + "width": 320, + "height": 725 + } }, { "data": { - "id": "note-Oz3TV", + "id": "note-K6vDt", "node": { "description": "# Travel Planning Agents \n\nThe travel planning system is a smart setup that uses several specialized \"agents\" to help plan incredible trips. Imagine each agent as a travel expert focusing on a part of your journey. Here's how it works:\n\n- **User-Friendly Start:** You start by telling the system about your travel needs—where you want to go and what you love to do.\n\n- **Data Collection:** The agents uses its tools to gather current info about various destinations, like the best travel times, weather, and costs.\n\n- **Three Key Agents:**\n - **City Selection Agent:** Picks the best places to visit based on your likes and current data.\n - **Local Expert Agent:** Gathers interesting details about what to do and see in the chosen city.\n - **Travel Concierge Agent:** Builds a day-by-day plan that includes where to stay, eat, and explore!\n\n- **Tools and Data:** Each agent uses tools to find and organize the latest information so you get recommendations that are both accurate and exciting.\n\n- **Final Plan:** Once everything is put together, you receive a complete, easy-to-follow travel itinerary, perfect for your adventure!\n", "display_name": "", @@ -2947,7 +2634,7 @@ }, "dragging": false, "height": 636, - "id": "note-Oz3TV", + "id": "note-K6vDt", "position": { "x": 1076.3710803600266, "y": 92.06058855045646 @@ -2963,11 +2650,15 @@ "width": 600 }, "type": "noteNode", - "width": 600 + "width": 600, + "measured": { + "width": 325, + "height": 636 + } }, { "data": { - "id": "note-Bdsjm", + "id": "note-kj8YE", "node": { "description": "# **City Selection Agent**\n - **Purpose:** This agent evaluates potential travel destinations based on user input and external data sources.\n - **Core Functions:** Analyzes factors such as weather, local events, and travel costs to recommend optimal cities.\n - **Tools Utilized:** Employs APIs and data-fetching tools to gather real-time information for decision-making.\n", "display_name": "", @@ -2980,7 +2671,7 @@ }, "dragging": false, "height": 362, - "id": "note-Bdsjm", + "id": "note-kj8YE", "position": { "x": 2122.4146132377227, "y": 485.2212661145467 @@ -2996,11 +2687,15 @@ "width": 331 }, "type": "noteNode", - "width": 331 + "width": 331, + "measured": { + "width": 325, + "height": 362 + } }, { "data": { - "id": "note-NgWM7", + "id": "note-523ch", "node": { "description": "# **Local Expert Agent**\n - **Purpose:** Focused on gathering and providing an in-depth guide to the selected city.\n - **Core Functions:** Compiles insights into cultural attractions, local customs, and unique experiences.\n - **Tools Utilized:** Uses web content fetchers and data APIs to collect detailed local insights and enhance the user understanding with hidden gems.\n", "display_name": "", @@ -3013,7 +2708,7 @@ }, "dragging": false, "height": 366, - "id": "note-NgWM7", + "id": "note-523ch", "position": { "x": 2827.660803823376, "y": 488.6092281195304 @@ -3029,11 +2724,15 @@ "width": 351 }, "type": "noteNode", - "width": 351 + "width": 351, + "measured": { + "width": 325, + "height": 366 + } }, { "data": { - "id": "note-EkH5J", + "id": "note-6RsAX", "node": { "description": "# **Travel Concierge Agent**\n - **Purpose:** Crafts detailed travel itineraries that are customized to the traveler's interests and needs.\n - **Core Functions:** Offers a comprehensive daily schedule, including accommodations, dining spots, and activities.\n - **Tools Utilized:** Integrates calculators and data tools for accurate budget planning and itinerary logistics.", "display_name": "", @@ -3046,7 +2745,7 @@ }, "dragging": false, "height": 344, - "id": "note-EkH5J", + "id": "note-6RsAX", "position": { "x": 3536.084279543714, "y": 496.3155992003396 @@ -3062,11 +2761,15 @@ "width": 344 }, "type": "noteNode", - "width": 344 + "width": 344, + "measured": { + "width": 325, + "height": 344 + } }, { "data": { - "id": "note-HlQ6g", + "id": "note-KT4sJ", "node": { "description": "## Configure the agent by obtaining your OpenAI API key from [platform.openai.com](https://platform.openai.com). Under \"Model Provider\", choose:\n- OpenAI: Default, requires only API key\n- Anthropic/Azure/Groq/NVIDIA: Each requires their own API keys\n- Custom: Use your own model endpoint + authentication\n\nSelect model and input API key before running the flow.", "display_name": "", @@ -3079,7 +2782,7 @@ }, "dragging": false, "height": 328, - "id": "note-HlQ6g", + "id": "note-KT4sJ", "position": { "x": 2463.3881993480218, "y": 42.83594355441298 @@ -3090,13 +2793,180 @@ }, "selected": false, "type": "noteNode", - "width": 328 + "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œ}" } ], "viewport": { - "x": -1078.5758749396496, - "y": -166.63499501100648, - "zoom": 0.6513143480813044 + "x": -1847.2791353675912, + "y": -230.9870437908569, + "zoom": 0.7659453992379711 } }, "description": "Create a travel planning chatbot that uses specialized agents to craft personalized trip itineraries.", @@ -3107,8 +2977,5 @@ "is_component": false, "last_tested_version": "1.0.19.post2", "name": "Travel Planning Agents", - "tags": [ - "agents", - "openai" - ] -} \ No newline at end of file + "tags": ["agents", "openai"] +}