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 c74c56ebbe67..af60317581ba 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,5 +1,283 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "TextInput", + "id": "TextInput-B04zJ", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "guidelines", + "id": "Prompt-kqSxX", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-TextInput-B04zJ{œdataTypeœ:œTextInputœ,œidœ:œTextInput-B04zJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-kqSxX{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "TextInput-B04zJ", + "sourceHandle": "{œdataTypeœ: œTextInputœ, œidœ: œTextInput-B04zJœ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-kqSxX", + "targetHandle": "{œfieldNameœ: œguidelinesœ, œidœ: œPrompt-kqSxXœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-BOLef", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "post", + "id": "Prompt-BwI7e", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-BOLef{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-BwI7e{œfieldNameœ:œpostœ,œidœ:œPrompt-BwI7eœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-BOLef", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-BOLefœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-BwI7e", + "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-BwI7eœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-kqSxX", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-BOLef", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-kqSxX{œdataTypeœ:œPromptœ,œidœ:œPrompt-kqSxXœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-BOLef{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BOLefœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-kqSxX", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-kqSxXœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-BOLef", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-BOLefœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "TavilyAISearch", + "id": "TavilyAISearch-HpBaM", + "name": "api_build_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-5FFry", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "reactflow__edge-TavilyAISearch-HpBaM{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-HpBaMœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-5FFry{œfieldNameœ:œtoolsœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "selected": false, + "source": "TavilyAISearch-HpBaM", + "sourceHandle": "{œdataTypeœ: œTavilyAISearchœ, œidœ: œTavilyAISearch-HpBaMœ, œnameœ: œapi_build_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-5FFry", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-5FFryœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-RXwSP", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-5FFry", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-RXwSP{œdataTypeœ:œChatInputœ,œidœ:œChatInput-RXwSPœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-5FFry{œfieldNameœ:œinput_valueœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "ChatInput-RXwSP", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-RXwSPœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-5FFry", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-5FFryœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-5FFry", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "context", + "id": "Prompt-kqSxX", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-5FFry{œdataTypeœ:œAgentœ,œidœ:œAgent-5FFryœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-kqSxX{œfieldNameœ:œcontextœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "Agent-5FFry", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-5FFryœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-kqSxX", + "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-kqSxXœ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "ran", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-BwI7e", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-5vp3N", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-BwI7e{œdataTypeœ:œPromptœ,œidœ:œPrompt-BwI7eœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-5vp3N{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-5vp3Nœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-BwI7e", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-BwI7eœ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "OpenAIModel-5vp3N", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-5vp3Nœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-BOLef", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "post", + "id": "Prompt-1yGW4", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-BOLef{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-1yGW4{œfieldNameœ:œpostœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-BOLef", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-BOLefœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-1yGW4", + "targetHandle": "{œfieldNameœ: œpostœ, œidœ: œPrompt-1yGW4œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": true, + "className": "running", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-5vp3N", + "name": "text_output", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "image_description", + "id": "Prompt-1yGW4", + "inputTypes": [ + "Message", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-5vp3N{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-5vp3Nœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-1yGW4{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-5vp3N", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-5vp3Nœ, œnameœ: œtext_outputœ, œoutput_typesœ: [œMessageœ]}", + "target": "Prompt-1yGW4", + "targetHandle": "{œfieldNameœ: œimage_descriptionœ, œidœ: œPrompt-1yGW4œ, œinputTypesœ: [œMessageœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "not-running", + "data": { + "sourceHandle": { + "dataType": "Prompt", + "id": "Prompt-1yGW4", + "name": "prompt", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-jWqJJ", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-1yGW4{œdataTypeœ:œPromptœ,œidœ:œPrompt-1yGW4œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-jWqJJ{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jWqJJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "source": "Prompt-1yGW4", + "sourceHandle": "{œdataTypeœ: œPromptœ, œidœ: œPrompt-1yGW4œ, œnameœ: œpromptœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-jWqJJ", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-jWqJJœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + } + ], "nodes": [ { "data": { @@ -276,6 +554,10 @@ "dragging": false, "height": 234, "id": "ChatInput-RXwSP", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 5183.264962599111, "y": 3024.7129453201533 @@ -286,11 +568,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -450,6 +728,10 @@ "dragging": false, "height": 433, "id": "Prompt-kqSxX", + "measured": { + "height": 433, + "width": 360 + }, "position": { "x": 6044.447585613556, "y": 2937.851014457363 @@ -460,11 +742,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 433 - } + "width": 320 }, { "data": { @@ -552,6 +830,10 @@ "dragging": false, "height": 234, "id": "TextInput-B04zJ", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 5663.277060522892, "y": 3512.0511890588114 @@ -562,11 +844,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -868,6 +1146,10 @@ "dragging": false, "height": 543, "id": "OpenAIModel-BOLef", + "measured": { + "height": 543, + "width": 360 + }, "position": { "x": 6427.182886017446, "y": 2891.554378731566 @@ -878,11 +1160,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 543 - } + "width": 320 }, { "data": { @@ -1018,6 +1296,10 @@ "dragging": false, "height": 347, "id": "Prompt-BwI7e", + "measured": { + "height": 347, + "width": 360 + }, "position": { "x": 6822.3853365255445, "y": 3031.299790790167 @@ -1028,11 +1310,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 347 - } + "width": 320 }, { "data": { @@ -1298,6 +1576,10 @@ "dragging": false, "height": 234, "id": "ChatOutput-jWqJJ", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 7980.617825443558, "y": 3377.2219674389726 @@ -1308,11 +1590,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -1869,254 +2147,254 @@ "type": "bool", "value": true } - }, - "tool_mode": false - }, - "type": "Agent" - }, - "dragging": false, - "height": 650, - "id": "Agent-5FFry", - "position": { - "x": 5665.465212822881, - "y": 2760.0819124193113 - }, - "positionAbsolute": { - "x": 5665.465212822881, - "y": 2760.0819124193113 - }, - "selected": false, - "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 650 - } - }, - { - "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 [DEPRECATED]", - "id": "TavilyAISearch-HpBaM", - "node": { + }, + "tool_mode": false + }, + "type": "Agent" + }, + "dragging": false, + "height": 650, + "id": "Agent-5FFry", + "measured": { + "height": 650, + "width": 360 + }, + "position": { + "x": 5665.465212822881, + "y": 2760.0819124193113 + }, + "positionAbsolute": { + "x": 5665.465212822881, + "y": 2760.0819124193113 + }, + "selected": false, + "type": "genericNode", + "width": 320 + }, + { + "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 [DEPRECATED]", + "id": "TavilyAISearch-HpBaM", + "node": { + "base_classes": [ + "Data", + "Tool" + ], + "beta": false, + "conditional_paths": [], + "custom_fields": {}, + "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n", + "display_name": "Tavily AI Search [DEPRECATED]", + "documentation": "https://docs.tavily.com/", + "edited": false, + "field_order": [ + "api_key", + "query", + "search_depth", + "topic", + "max_results", + "include_images", + "include_answer" + ], + "frozen": false, + "icon": "TavilyIcon", + "legacy": true, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Data", + "method": "run_model", + "name": "api_run_model", + "required_inputs": [ + "api_key" + ], + "selected": "Data", + "types": [ + "Data" + ], + "value": "__UNDEFINED__" + }, + { + "cache": true, + "display_name": "Tool", + "method": "build_tool", + "name": "api_build_tool", + "required_inputs": [ + "api_key" + ], + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, "template": { "_type": "Component", "api_key": { - "load_from_db": false, - "required": true, - "placeholder": "", - "show": true, - "name": "api_key", - "value": "", - "display_name": "Tavily API Key", + "_input_type": "SecretStrInput", "advanced": false, + "display_name": "Tavily API Key", + "dynamic": false, + "info": "Your Tavily API Key.", "input_types": [ "Message" ], - "dynamic": false, - "info": "Your Tavily API Key.", - "title_case": false, + "load_from_db": false, + "name": "api_key", "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, "type": "str", - "_input_type": "SecretStrInput" + "value": "" }, "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, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from enum import Enum\n\nimport httpx\nfrom langchain.tools import StructuredTool\nfrom langchain_core.tools import ToolException\nfrom loguru import logger\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import BoolInput, DropdownInput, IntInput, MessageTextInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass TavilySearchDepth(Enum):\n BASIC = \"basic\"\n ADVANCED = \"advanced\"\n\n\nclass TavilySearchTopic(Enum):\n GENERAL = \"general\"\n NEWS = \"news\"\n\n\nclass TavilySearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query you want to execute with Tavily.\")\n search_depth: TavilySearchDepth = Field(TavilySearchDepth.BASIC, description=\"The depth of the search.\")\n topic: TavilySearchTopic = Field(TavilySearchTopic.GENERAL, description=\"The category of the search.\")\n max_results: int = Field(5, description=\"The maximum number of search results to return.\")\n include_images: bool = Field(default=False, description=\"Include a list of query-related images in the response.\")\n include_answer: bool = Field(default=False, description=\"Include a short answer to original query.\")\n\n\nclass TavilySearchToolComponent(LCToolComponent):\n display_name = \"Tavily AI Search [DEPRECATED]\"\n description = \"\"\"**Tavily AI** is a search engine optimized for LLMs and RAG, \\\n aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n\"\"\"\n icon = \"TavilyIcon\"\n name = \"TavilyAISearch\"\n documentation = \"https://docs.tavily.com/\"\n legacy = True\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"Tavily API Key\",\n required=True,\n info=\"Your Tavily API Key.\",\n ),\n MessageTextInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The search query you want to execute with Tavily.\",\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=list(TavilySearchDepth),\n value=TavilySearchDepth.ADVANCED,\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=list(TavilySearchTopic),\n value=TavilySearchTopic.GENERAL,\n advanced=True,\n ),\n IntInput(\n name=\"max_results\",\n display_name=\"Max Results\",\n info=\"The maximum number of search results to return.\",\n value=5,\n advanced=True,\n ),\n BoolInput(\n name=\"include_images\",\n display_name=\"Include Images\",\n info=\"Include a list of query-related images in the response.\",\n value=True,\n advanced=True,\n ),\n BoolInput(\n name=\"include_answer\",\n display_name=\"Include Answer\",\n info=\"Include a short answer to original query.\",\n value=True,\n advanced=True,\n ),\n ]\n\n def run_model(self) -> list[Data]:\n # Convert string values to enum instances with validation\n try:\n search_depth_enum = (\n self.search_depth\n if isinstance(self.search_depth, TavilySearchDepth)\n else TavilySearchDepth(str(self.search_depth).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid search depth value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n try:\n topic_enum = (\n self.topic if isinstance(self.topic, TavilySearchTopic) else TavilySearchTopic(str(self.topic).lower())\n )\n except ValueError as e:\n error_message = f\"Invalid topic value: {e!s}\"\n self.status = error_message\n return [Data(data={\"error\": error_message})]\n\n return self._tavily_search(\n self.query,\n search_depth=search_depth_enum,\n topic=topic_enum,\n max_results=self.max_results,\n include_images=self.include_images,\n include_answer=self.include_answer,\n )\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"tavily_search\",\n description=\"Perform a web search using the Tavily API.\",\n func=self._tavily_search,\n args_schema=TavilySearchSchema,\n )\n\n def _tavily_search(\n self,\n query: str,\n *,\n search_depth: TavilySearchDepth = TavilySearchDepth.BASIC,\n topic: TavilySearchTopic = TavilySearchTopic.GENERAL,\n max_results: int = 5,\n include_images: bool = False,\n include_answer: bool = False,\n ) -> list[Data]:\n # Validate enum values\n if not isinstance(search_depth, TavilySearchDepth):\n msg = f\"Invalid search_depth value: {search_depth}\"\n raise TypeError(msg)\n if not isinstance(topic, TavilySearchTopic):\n msg = f\"Invalid topic value: {topic}\"\n raise TypeError(msg)\n\n try:\n url = \"https://api.tavily.com/search\"\n headers = {\n \"content-type\": \"application/json\",\n \"accept\": \"application/json\",\n }\n payload = {\n \"api_key\": self.api_key,\n \"query\": query,\n \"search_depth\": search_depth.value,\n \"topic\": topic.value,\n \"max_results\": max_results,\n \"include_images\": include_images,\n \"include_answer\": include_answer,\n }\n\n with httpx.Client() as client:\n response = client.post(url, json=payload, headers=headers)\n\n response.raise_for_status()\n search_results = response.json()\n\n data_results = [\n Data(\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": result.get(\"content\"),\n \"score\": result.get(\"score\"),\n }\n )\n for result in search_results.get(\"results\", [])\n ]\n\n if include_answer and search_results.get(\"answer\"):\n data_results.insert(0, Data(data={\"answer\": search_results[\"answer\"]}))\n\n if include_images and search_results.get(\"images\"):\n data_results.append(Data(data={\"images\": search_results[\"images\"]}))\n\n self.status = data_results # type: ignore[assignment]\n\n except httpx.HTTPStatusError as e:\n error_message = f\"HTTP error: {e.response.status_code} - {e.response.text}\"\n logger.debug(error_message)\n self.status = error_message\n raise ToolException(error_message) from e\n except Exception as e:\n error_message = f\"Unexpected error: {e}\"\n logger.opt(exception=True).debug(\"Error running Tavily Search\")\n self.status = error_message\n raise ToolException(error_message) from e\n return data_results\n" }, "include_answer": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Answer", + "dynamic": false, + "info": "Include a short answer to original query.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "include_answer", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "bool", - "_input_type": "BoolInput" + "value": true }, "include_images": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Images", + "dynamic": false, + "info": "Include a list of query-related images in the response.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "include_images", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "bool", - "_input_type": "BoolInput" + "value": true }, "max_results": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Results", + "dynamic": false, + "info": "The maximum number of search results to return.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "max_results", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "int", - "_input_type": "IntInput" + "value": 5 }, "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", + "_input_type": "MessageTextInput", "advanced": false, + "display_name": "Search Query", + "dynamic": false, + "info": "The search query you want to execute with Tavily.", "input_types": [ "Message" ], - "dynamic": false, - "info": "The search query you want to execute with Tavily.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "query", + "placeholder": "", + "required": false, + "show": true, "title_case": false, + "tool_mode": false, + "trace_as_input": true, + "trace_as_metadata": true, "type": "str", - "_input_type": "MessageTextInput" + "value": "" }, "search_depth": { - "tool_mode": false, - "trace_as_metadata": true, + "_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" ], - "combobox": false, - "required": false, "placeholder": "", + "required": false, "show": true, - "name": "search_depth", - "value": "advanced", - "display_name": "Search Depth", - "advanced": true, - "dynamic": false, - "info": "The depth of the search.", "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false + "value": "advanced" }, "topic": { - "tool_mode": false, - "trace_as_metadata": true, + "_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" ], - "combobox": false, - "required": false, "placeholder": "", + "required": false, "show": true, - "name": "topic", - "value": "general", - "display_name": "Search Topic", - "advanced": true, - "dynamic": false, - "info": "The category of the search.", "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, "type": "str", - "_input_type": "DropdownInput", - "load_from_db": false + "value": "general" } }, - "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results. It can be used independently or as an agent tool.\n\nNote: Check 'Advanced' for all options.\n", - "icon": "TavilyIcon", - "base_classes": [ - "Data", - "Tool" - ], - "display_name": "Tavily AI Search [DEPRECATED]", - "documentation": "https://docs.tavily.com/", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": [ - "Data" - ], - "selected": "Data", - "name": "api_run_model", - "display_name": "Data", - "method": "run_model", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [ - "api_key" - ] - }, - { - "types": [ - "Tool" - ], - "selected": "Tool", - "name": "api_build_tool", - "display_name": "Tool", - "method": "build_tool", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": [ - "api_key" - ] - } - ], - "field_order": [ - "api_key", - "query", - "search_depth", - "topic", - "max_results", - "include_images", - "include_answer" - ], - "beta": false, - "legacy": true, - "edited": false, - "metadata": {}, "tool_mode": false }, "type": "TavilyAISearch" @@ -2124,6 +2402,10 @@ "dragging": false, "height": 481, "id": "TavilyAISearch-HpBaM", + "measured": { + "height": 481, + "width": 360 + }, "position": { "x": 5178.005987190226, "y": 3496.7214582697484 @@ -2134,11 +2416,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 481 - } + "width": 320 }, { "data": { @@ -2440,6 +2718,10 @@ "dragging": false, "height": 543, "id": "OpenAIModel-5vp3N", + "measured": { + "height": 543, + "width": 360 + }, "position": { "x": 7211.829041441037, "y": 2938.1023670807563 @@ -2450,11 +2732,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 543 - } + "width": 320 }, { "data": { @@ -2614,6 +2892,10 @@ "dragging": false, "height": 433, "id": "Prompt-1yGW4", + "measured": { + "height": 433, + "width": 360 + }, "position": { "x": 7613.837241084599, "y": 3139.8282595890087 @@ -2623,456 +2905,174 @@ "y": 3139.8282595890087 }, "selected": false, - "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 433 - } - }, - { - "data": { - "id": "note-xa2dd", - "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": "", - "documentation": "", - "template": { - "backgroundColor": "amber" - } - }, - "type": "note" - }, - "dragging": false, - "height": 648, - "id": "note-xa2dd", - "position": { - "x": 4492.051129290571, - "y": 2746.336592524463 - }, - "positionAbsolute": { - "x": 4560.051129290571, - "y": 2746.336592524463 - }, - "resizing": false, - "selected": false, - "style": { - "height": 648, - "width": 554 - }, - "type": "noteNode", - "width": 554, - "measured": { - "width": 328, - "height": 648 - } - }, - { - "data": { - "id": "note-Odqui", - "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": "", - "documentation": "", - "template": { - "backgroundColor": "blue" - } - }, - "type": "note" - }, - "dragging": false, - "height": 325, - "id": "note-Odqui", - "position": { - "x": 5667.476249937603, - "y": 3644.9055828357396 - }, - "positionAbsolute": { - "x": 5667.476249937603, - "y": 3644.9055828357396 - }, - "resizing": false, - "selected": false, - "type": "noteNode", - "width": 325, - "measured": { - "width": 328, - "height": 325 - } - }, - { - "data": { - "id": "note-uwin1", - "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": "", - "documentation": "", - "template": { - "backgroundColor": "blue" - } - }, - "type": "note" - }, - "dragging": false, - "height": 325, - "id": "note-uwin1", - "position": { - "x": 6786.375917286389, - "y": 3393.8522072000146 - }, - "positionAbsolute": { - "x": 6786.375917286389, - "y": 3393.8522072000146 - }, - "selected": false, - "type": "noteNode", - "width": 325, - "measured": { - "width": 328, - "height": 325 - } - }, - { - "data": { - "id": "note-GVjGk", - "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": "", - "documentation": "", - "template": { - "backgroundColor": "blue" - } - }, - "type": "note" - }, - "dragging": false, - "height": 325, - "id": "note-GVjGk", - "position": { - "x": 7606.419013912975, - "y": 3612.8149429707646 - }, - "positionAbsolute": { - "x": 7606.419013912975, - "y": 3612.8149429707646 - }, - "selected": false, - "type": "noteNode", - "width": 325, - "measured": { - "width": 328, - "height": 325 - } - }, - { - "data": { - "id": "note-PjdDf", - "node": { - "description": "# 🔑 Tavily AI Search Needs API Key\n\nYou can get 1000 searches/month free [here](https://tavily.com/) ", - "display_name": "", - "documentation": "", - "template": { - "backgroundColor": "lime" - } - }, - "type": "note" - }, - "dragging": false, - "height": 325, - "id": "note-PjdDf", - "position": { - "x": 5174.678177457385, - "y": 3339.6628854203204 - }, - "positionAbsolute": { - "x": 5174.678177457385, - "y": 3339.6628854203204 - }, - "selected": false, - "type": "noteNode", - "width": 325, - "measured": { - "width": 328, - "height": 325 - } - } - ], - "edges": [ - { - "animated": false, - "className": "not-running", - "data": { - "sourceHandle": { - "dataType": "TextInput", - "id": "TextInput-B04zJ", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "guidelines", - "id": "Prompt-kqSxX", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-TextInput-B04zJ{œdataTypeœ:œTextInputœ,œidœ:œTextInput-B04zJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-Prompt-kqSxX{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "TextInput-B04zJ", - "sourceHandle": "{œdataTypeœ:œTextInputœ,œidœ:œTextInput-B04zJœ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-kqSxX", - "targetHandle": "{œfieldNameœ:œguidelinesœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "not-running", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-BOLef", - "name": "text_output", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-BwI7e", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-BOLef{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-BwI7e{œfieldNameœ:œpostœ,œidœ:œPrompt-BwI7eœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-BOLef", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-BwI7e", - "targetHandle": "{œfieldNameœ:œpostœ,œidœ:œPrompt-BwI7eœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "not-running", - "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-kqSxX", - "name": "prompt", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-BOLef", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-kqSxX{œdataTypeœ:œPromptœ,œidœ:œPrompt-kqSxXœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-BOLef{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BOLefœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-kqSxX", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-kqSxXœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-BOLef", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-BOLefœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "not-running", - "data": { - "sourceHandle": { - "dataType": "TavilyAISearch", - "id": "TavilyAISearch-HpBaM", - "name": "api_build_tool", - "output_types": [ - "Tool" - ] - }, - "targetHandle": { - "fieldName": "tools", - "id": "Agent-5FFry", - "inputTypes": [ - "Tool" - ], - "type": "other" - } - }, - "id": "reactflow__edge-TavilyAISearch-HpBaM{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-HpBaMœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}-Agent-5FFry{œfieldNameœ:œtoolsœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "selected": false, - "source": "TavilyAISearch-HpBaM", - "sourceHandle": "{œdataTypeœ:œTavilyAISearchœ,œidœ:œTavilyAISearch-HpBaMœ,œnameœ:œapi_build_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-5FFry", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" + "type": "genericNode", + "width": 320 }, { - "animated": false, - "className": "not-running", "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-RXwSP", - "name": "message", - "output_types": [ - "Message" - ] + "id": "note-xa2dd", + "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": "", + "documentation": "", + "template": { + "backgroundColor": "amber" + } }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-5FFry", - "inputTypes": [ - "Message" - ], - "type": "str" - } + "type": "note" }, - "id": "reactflow__edge-ChatInput-RXwSP{œdataTypeœ:œChatInputœ,œidœ:œChatInput-RXwSPœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-5FFry{œfieldNameœ:œinput_valueœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "ChatInput-RXwSP", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-RXwSPœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-5FFry", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-5FFryœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "not-running", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-5FFry", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-kqSxX", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } + "dragging": false, + "height": 648, + "id": "note-xa2dd", + "measured": { + "height": 648, + "width": 328 }, - "id": "reactflow__edge-Agent-5FFry{œdataTypeœ:œAgentœ,œidœ:œAgent-5FFryœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-Prompt-kqSxX{œfieldNameœ:œcontextœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "Agent-5FFry", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-5FFryœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-kqSxX", - "targetHandle": "{œfieldNameœ:œcontextœ,œidœ:œPrompt-kqSxXœ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" + "position": { + "x": 4492.051129290571, + "y": 2746.336592524463 + }, + "positionAbsolute": { + "x": 4560.051129290571, + "y": 2746.336592524463 + }, + "resizing": false, + "selected": false, + "style": { + "height": 648, + "width": 554 + }, + "type": "noteNode", + "width": 554 }, { - "animated": false, - "className": "ran", "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-BwI7e", - "name": "prompt", - "output_types": [ - "Message" - ] + "id": "note-Odqui", + "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": "", + "documentation": "", + "template": { + "backgroundColor": "blue" + } }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-5vp3N", - "inputTypes": [ - "Message" - ], - "type": "str" - } + "type": "note" }, - "id": "reactflow__edge-Prompt-BwI7e{œdataTypeœ:œPromptœ,œidœ:œPrompt-BwI7eœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-OpenAIModel-5vp3N{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-5vp3Nœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-BwI7e", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-BwI7eœ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "OpenAIModel-5vp3N", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-5vp3Nœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" + "dragging": false, + "height": 325, + "id": "note-Odqui", + "measured": { + "height": 325, + "width": 328 + }, + "position": { + "x": 5667.476249937603, + "y": 3644.9055828357396 + }, + "positionAbsolute": { + "x": 5667.476249937603, + "y": 3644.9055828357396 + }, + "resizing": false, + "selected": false, + "type": "noteNode", + "width": 325 }, { - "animated": false, - "className": "not-running", "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-BOLef", - "name": "text_output", - "output_types": [ - "Message" - ] + "id": "note-uwin1", + "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": "", + "documentation": "", + "template": { + "backgroundColor": "blue" + } }, - "targetHandle": { - "fieldName": "post", - "id": "Prompt-1yGW4", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } + "type": "note" }, - "id": "reactflow__edge-OpenAIModel-BOLef{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-1yGW4{œfieldNameœ:œpostœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-BOLef", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-BOLefœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-1yGW4", - "targetHandle": "{œfieldNameœ:œpostœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" + "dragging": false, + "height": 325, + "id": "note-uwin1", + "measured": { + "height": 325, + "width": 328 + }, + "position": { + "x": 6786.375917286389, + "y": 3393.8522072000146 + }, + "positionAbsolute": { + "x": 6786.375917286389, + "y": 3393.8522072000146 + }, + "selected": false, + "type": "noteNode", + "width": 325 }, { - "animated": true, - "className": "running", "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-5vp3N", - "name": "text_output", - "output_types": [ - "Message" - ] + "id": "note-GVjGk", + "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": "", + "documentation": "", + "template": { + "backgroundColor": "blue" + } }, - "targetHandle": { - "fieldName": "image_description", - "id": "Prompt-1yGW4", - "inputTypes": [ - "Message", - "Text" - ], - "type": "str" - } + "type": "note" }, - "id": "reactflow__edge-OpenAIModel-5vp3N{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-5vp3Nœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}-Prompt-1yGW4{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-5vp3N", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-5vp3Nœ,œnameœ:œtext_outputœ,œoutput_typesœ:[œMessageœ]}", - "target": "Prompt-1yGW4", - "targetHandle": "{œfieldNameœ:œimage_descriptionœ,œidœ:œPrompt-1yGW4œ,œinputTypesœ:[œMessageœ,œTextœ],œtypeœ:œstrœ}" + "dragging": false, + "height": 325, + "id": "note-GVjGk", + "measured": { + "height": 325, + "width": 328 + }, + "position": { + "x": 7606.419013912975, + "y": 3612.8149429707646 + }, + "positionAbsolute": { + "x": 7606.419013912975, + "y": 3612.8149429707646 + }, + "selected": false, + "type": "noteNode", + "width": 325 }, { - "animated": false, - "className": "not-running", "data": { - "sourceHandle": { - "dataType": "Prompt", - "id": "Prompt-1yGW4", - "name": "prompt", - "output_types": [ - "Message" - ] + "id": "note-PjdDf", + "node": { + "description": "# 🔑 Tavily AI Search Needs API Key\n\nYou can get 1000 searches/month free [here](https://tavily.com/) ", + "display_name": "", + "documentation": "", + "template": { + "backgroundColor": "lime" + } }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-jWqJJ", - "inputTypes": [ - "Message" - ], - "type": "str" - } + "type": "note" }, - "id": "reactflow__edge-Prompt-1yGW4{œdataTypeœ:œPromptœ,œidœ:œPrompt-1yGW4œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-jWqJJ{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jWqJJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "source": "Prompt-1yGW4", - "sourceHandle": "{œdataTypeœ:œPromptœ,œidœ:œPrompt-1yGW4œ,œnameœ:œpromptœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-jWqJJ", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-jWqJJœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" + "dragging": false, + "height": 325, + "id": "note-PjdDf", + "measured": { + "height": 325, + "width": 328 + }, + "position": { + "x": 5174.678177457385, + "y": 3339.6628854203204 + }, + "positionAbsolute": { + "x": 5174.678177457385, + "y": 3339.6628854203204 + }, + "selected": false, + "type": "noteNode", + "width": 325 } ], "viewport": { diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json index 2294e2548128..991a1524d3bd 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Market Research.json @@ -1,5 +1,172 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "OpenAIModel", + "id": "OpenAIModel-qEjqV", + "name": "model_output", + "output_types": [ + "LanguageModel" + ] + }, + "targetHandle": { + "fieldName": "llm", + "id": "StructuredOutputComponent-Fk5AM", + "inputTypes": [ + "LanguageModel" + ], + "type": "other" + } + }, + "id": "reactflow__edge-OpenAIModel-qEjqV{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-qEjqVœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutputComponent-Fk5AM{œfieldNameœ:œllmœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", + "selected": false, + "source": "OpenAIModel-qEjqV", + "sourceHandle": "{œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-qEjqVœ, œnameœ: œmodel_outputœ, œoutput_typesœ: [œLanguageModelœ]}", + "target": "StructuredOutputComponent-Fk5AM", + "targetHandle": "{œfieldNameœ: œllmœ, œidœ: œStructuredOutputComponent-Fk5AMœ, œinputTypesœ: [œLanguageModelœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "StructuredOutputComponent", + "id": "StructuredOutputComponent-Fk5AM", + "name": "structured_output", + "output_types": [ + "Data" + ] + }, + "targetHandle": { + "fieldName": "data", + "id": "ParseData-zFzM6", + "inputTypes": [ + "Data" + ], + "type": "other" + } + }, + "id": "reactflow__edge-StructuredOutputComponent-Fk5AM{œdataTypeœ:œStructuredOutputComponentœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-ParseData-zFzM6{œfieldNameœ:œdataœ,œidœ:œParseData-zFzM6œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", + "selected": false, + "source": "StructuredOutputComponent-Fk5AM", + "sourceHandle": "{œdataTypeœ: œStructuredOutputComponentœ, œidœ: œStructuredOutputComponent-Fk5AMœ, œnameœ: œstructured_outputœ, œoutput_typesœ: [œDataœ]}", + "target": "ParseData-zFzM6", + "targetHandle": "{œfieldNameœ: œdataœ, œidœ: œParseData-zFzM6œ, œinputTypesœ: [œDataœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ParseData", + "id": "ParseData-zFzM6", + "name": "text", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-NJfzg", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ParseData-zFzM6{œdataTypeœ:œParseDataœ,œidœ:œParseData-zFzM6œ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-NJfzg{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-NJfzgœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ParseData-zFzM6", + "sourceHandle": "{œdataTypeœ: œParseDataœ, œidœ: œParseData-zFzM6œ, œnameœ: œtextœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-NJfzg", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-NJfzgœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-N6esY", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-axUVK", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-N6esY{œdataTypeœ:œChatInputœ,œidœ:œChatInput-N6esYœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-axUVK{œfieldNameœ:œinput_valueœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-N6esY", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-N6esYœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-axUVK", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-axUVKœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-axUVK", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "StructuredOutputComponent-Fk5AM", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-axUVK{œdataTypeœ:œAgentœ,œidœ:œAgent-axUVKœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-StructuredOutputComponent-Fk5AM{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Agent-axUVK", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-axUVKœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "StructuredOutputComponent-Fk5AM", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œStructuredOutputComponent-Fk5AMœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "data": { + "sourceHandle": { + "dataType": "TavilySearchComponent", + "id": "TavilySearchComponent-J0fu0", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-axUVK", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__TavilySearchComponent-J0fu0{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-J0fu0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-axUVK{œfieldNameœ:œtoolsœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "TavilySearchComponent-J0fu0", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-J0fu0œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-axUVK", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-axUVKœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { @@ -278,6 +445,10 @@ "dragging": false, "height": 234, "id": "ChatInput-N6esY", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 472.38251755471583, "y": 889.8398446936101 @@ -288,11 +459,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -559,6 +726,10 @@ "dragging": false, "height": 234, "id": "ChatOutput-NJfzg", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 2518.282039019285, "y": 855.3686932779933 @@ -569,11 +740,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -591,6 +758,10 @@ "dragging": false, "height": 403, "id": "note-40RoE", + "measured": { + "height": 403, + "width": 328 + }, "position": { "x": 2089.5869930853464, "y": 311.41660832449514 @@ -606,11 +777,7 @@ "width": 461 }, "type": "noteNode", - "width": 461, - "measured": { - "width": 328, - "height": 403 - } + "width": 461 }, { "data": { @@ -628,6 +795,10 @@ "dragging": false, "height": 382, "id": "note-hgOqR", + "measured": { + "height": 382, + "width": 328 + }, "position": { "x": 1237.6627823432912, "y": 111.53860932079613 @@ -643,11 +814,7 @@ "width": 398 }, "type": "noteNode", - "width": 398, - "measured": { - "width": 328, - "height": 382 - } + "width": 398 }, { "data": { @@ -665,6 +832,10 @@ "dragging": false, "height": 513, "id": "note-ifPGq", + "measured": { + "height": 513, + "width": 328 + }, "position": { "x": 244.92297036777086, "y": 340.99805740871204 @@ -680,11 +851,7 @@ "width": 567 }, "type": "noteNode", - "width": 567, - "measured": { - "width": 328, - "height": 513 - } + "width": 567 }, { "data": { @@ -951,6 +1118,10 @@ "dragging": false, "height": 541, "id": "StructuredOutputComponent-Fk5AM", + "measured": { + "height": 541, + "width": 360 + }, "position": { "x": 1716.7237308033855, "y": 459.2476214962564 @@ -961,11 +1132,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 541 - } + "width": 320 }, { "data": { @@ -1267,6 +1434,10 @@ "dragging": false, "height": 543, "id": "OpenAIModel-qEjqV", + "measured": { + "height": 543, + "width": 360 + }, "position": { "x": 1696.6021757625274, "y": 1053.2300549755305 @@ -1277,11 +1448,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 543 - } + "width": 320 }, { "data": { @@ -1421,6 +1588,10 @@ "dragging": false, "height": 302, "id": "ParseData-zFzM6", + "measured": { + "height": 302, + "width": 360 + }, "position": { "x": 2139.05558520377, "y": 780.6849187394922 @@ -1431,11 +1602,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 302 - } + "width": 320 }, { "data": { @@ -2001,17 +2168,17 @@ "dragging": false, "height": 650, "id": "Agent-axUVK", + "measured": { + "height": 650, + "width": 360 + }, "position": { "x": 1287.5681517817056, "y": 519.8701526087884 }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 650 - } + "width": 320 }, { "data": { @@ -2029,6 +2196,10 @@ "dragging": false, "height": 325, "id": "note-NrsCo", + "measured": { + "height": 325, + "width": 328 + }, "position": { "x": 878.7898510090017, "y": 640.2524241641511 @@ -2039,506 +2210,335 @@ }, "selected": false, "type": "noteNode", - "width": 325, - "measured": { - "width": 328, - "height": 325 - } + "width": 325 }, { - "id": "TavilySearchComponent-J0fu0", - "type": "genericNode", - "position": { - "x": 875.7686789989679, - "y": 798.478848045035 - }, "data": { + "id": "TavilySearchComponent-J0fu0", "node": { + "base_classes": [ + "Data", + "Message" + ], + "beta": false, + "category": "tools", + "conditional_paths": [], + "custom_fields": {}, + "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", + "display_name": "Tavily AI Search", + "documentation": "", + "edited": false, + "field_order": [ + "api_key", + "query", + "search_depth", + "topic", + "max_results", + "include_images", + "include_answer" + ], + "frozen": false, + "icon": "TavilyIcon", + "key": "TavilySearchComponent", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "score": 0.0075846556637275304, "template": { "_type": "Component", "api_key": { - "load_from_db": false, - "required": true, - "placeholder": "", - "show": true, - "name": "api_key", - "value": "", - "display_name": "Tavily API Key", + "_input_type": "SecretStrInput", "advanced": false, + "display_name": "Tavily API Key", + "dynamic": false, + "info": "Your Tavily API Key.", "input_types": [ "Message" ], - "dynamic": false, - "info": "Your Tavily API Key.", - "title_case": false, + "load_from_db": false, + "name": "api_key", "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, "type": "str", - "_input_type": "SecretStrInput" + "value": "" }, "code": { - "type": "code", - "required": true, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageTextInput, Output, SecretStrInput\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass TavilySearchComponent(Component):\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.\"\"\"\n icon = \"TavilyIcon\"\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 tool_mode=True,\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=[\"basic\", \"advanced\"],\n value=\"advanced\",\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=[\"general\", \"news\"],\n value=\"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 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 fetch_content(self) -> list[Data]:\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\": self.query,\n \"search_depth\": self.search_depth,\n \"topic\": self.topic,\n \"max_results\": self.max_results,\n \"include_images\": self.include_images,\n \"include_answer\": self.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\n if self.include_answer and search_results.get(\"answer\"):\n data_results.append(Data(text=search_results[\"answer\"]))\n\n for result in search_results.get(\"results\", []):\n content = result.get(\"content\", \"\")\n data_results.append(\n Data(\n text=content,\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": content,\n \"score\": result.get(\"score\"),\n },\n )\n )\n\n if self.include_images and search_results.get(\"images\"):\n data_results.append(Data(text=\"Images found\", data={\"images\": search_results[\"images\"]}))\n except httpx.HTTPStatusError as exc:\n error_message = f\"HTTP error occurred: {exc.response.status_code} - {exc.response.text}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n except httpx.RequestError as exc:\n error_message = f\"Request error occurred: {exc}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n except ValueError as exc:\n error_message = f\"Invalid response format: {exc}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n else:\n self.status = data_results\n return data_results\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageTextInput, Output, SecretStrInput\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\n\n\nclass TavilySearchComponent(Component):\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.\"\"\"\n icon = \"TavilyIcon\"\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 tool_mode=True,\n ),\n DropdownInput(\n name=\"search_depth\",\n display_name=\"Search Depth\",\n info=\"The depth of the search.\",\n options=[\"basic\", \"advanced\"],\n value=\"advanced\",\n advanced=True,\n ),\n DropdownInput(\n name=\"topic\",\n display_name=\"Search Topic\",\n info=\"The category of the search.\",\n options=[\"general\", \"news\"],\n value=\"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 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 fetch_content(self) -> list[Data]:\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\": self.query,\n \"search_depth\": self.search_depth,\n \"topic\": self.topic,\n \"max_results\": self.max_results,\n \"include_images\": self.include_images,\n \"include_answer\": self.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\n if self.include_answer and search_results.get(\"answer\"):\n data_results.append(Data(text=search_results[\"answer\"]))\n\n for result in search_results.get(\"results\", []):\n content = result.get(\"content\", \"\")\n data_results.append(\n Data(\n text=content,\n data={\n \"title\": result.get(\"title\"),\n \"url\": result.get(\"url\"),\n \"content\": content,\n \"score\": result.get(\"score\"),\n },\n )\n )\n\n if self.include_images and search_results.get(\"images\"):\n data_results.append(Data(text=\"Images found\", data={\"images\": search_results[\"images\"]}))\n except httpx.HTTPStatusError as exc:\n error_message = f\"HTTP error occurred: {exc.response.status_code} - {exc.response.text}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n except httpx.RequestError as exc:\n error_message = f\"Request error occurred: {exc}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n except ValueError as exc:\n error_message = f\"Invalid response format: {exc}\"\n logger.error(error_message)\n return [Data(text=error_message, data={\"error\": error_message})]\n else:\n self.status = data_results\n return data_results\n\n def fetch_content_text(self) -> Message:\n data = self.fetch_content()\n result_string = data_to_text(\"{text}\", data)\n self.status = result_string\n return Message(text=result_string)\n" }, "include_answer": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Answer", + "dynamic": false, + "info": "Include a short answer to original query.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "include_answer", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "bool", - "_input_type": "BoolInput" + "value": true }, "include_images": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Include Images", + "dynamic": false, + "info": "Include a list of query-related images in the response.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "include_images", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "bool", - "_input_type": "BoolInput" + "value": true }, "max_results": { - "tool_mode": false, - "trace_as_metadata": true, + "_input_type": "IntInput", + "advanced": true, + "display_name": "Max Results", + "dynamic": false, + "info": "The maximum number of search results to return.", "list": false, "list_add_label": "Add More", - "required": false, + "name": "max_results", "placeholder": "", + "required": false, "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "int", - "_input_type": "IntInput" + "value": 5 }, "query": { - "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": "query", - "value": "", - "display_name": "Search 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" ], - "dynamic": false, - "info": "The search query you want to execute with Tavily.", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "query", + "placeholder": "", + "required": false, + "show": true, "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, "type": "str", - "_input_type": "MessageTextInput" + "value": "" }, "search_depth": { - "tool_mode": false, - "trace_as_metadata": true, - "options": [ - "basic", - "advanced" - ], + "_input_type": "DropdownInput", + "advanced": true, "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" - }, - "topic": { - "tool_mode": false, - "trace_as_metadata": true, + "name": "search_depth", "options": [ - "general", - "news" + "basic", + "advanced" ], - "combobox": false, - "required": false, "placeholder": "", + "required": false, "show": true, - "name": "topic", - "value": "general", - "display_name": "Search Topic", - "advanced": true, - "dynamic": false, - "info": "The category of the search.", "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, "type": "str", - "_input_type": "DropdownInput" + "value": "advanced" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "table_icon": "Hammer", + "table_options": { + "block_add": true, + "block_delete": true, + "block_edit": true, + "block_filter": true, + "block_hide": true, + "block_select": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "field_parsers": { + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] + }, + "hide_options": true + }, "table_schema": { "columns": [ { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", "description": "Specify the name of the tool.", "disable_edit": false, + "display_name": "Tool Name", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" }, { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", "description": "Describe the purpose of the tool.", "disable_edit": false, + "display_name": "Tool Description", "edit_mode": "popover", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "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, + "display_name": "Tool Identifiers", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" }, { - "name": "commands", - "display_name": "Commands", - "sortable": false, - "filterable": 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", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "commands", + "sortable": false, + "type": "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." - }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "None-fetch_content", "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" ] }, { - "name": "None-fetch_content_text", "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" ] } - ], - "display_name": "Edit tools", - "advanced": false, + ] + }, + "topic": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "display_name": "Search Topic", "dynamic": false, - "info": "", - "real_time_refresh": true, - "title_case": false, - "type": "table", - "_input_type": "TableInput" - } - }, - "description": "**Tavily AI** is a search engine optimized for LLMs and RAG, aimed at efficient, quick, and persistent search results.", - "icon": "TavilyIcon", - "base_classes": [ - "Data", - "Message" - ], - "display_name": "Tavily AI Search", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": [ - "Tool" + "info": "The category of the search.", + "name": "topic", + "options": [ + "general", + "news" ], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": null + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "general" } - ], - "field_order": [ - "api_key", - "query", - "search_depth", - "topic", - "max_results", - "include_images", - "include_answer" - ], - "beta": false, - "legacy": false, - "edited": false, - "metadata": {}, - "category": "tools", - "key": "TavilySearchComponent", - "score": 0.0075846556637275304 + } }, "showNode": true, - "type": "TavilySearchComponent", - "id": "TavilySearchComponent-J0fu0" + "type": "TavilySearchComponent" }, - "selected": true, + "dragging": false, + "id": "TavilySearchComponent-J0fu0", "measured": { - "width": 360, - "height": 489 - }, - "dragging": false - } - ], - "edges": [ - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "OpenAIModel", - "id": "OpenAIModel-qEjqV", - "name": "model_output", - "output_types": [ - "LanguageModel" - ] - }, - "targetHandle": { - "fieldName": "llm", - "id": "StructuredOutputComponent-Fk5AM", - "inputTypes": [ - "LanguageModel" - ], - "type": "other" - } + "height": 489, + "width": 360 }, - "id": "reactflow__edge-OpenAIModel-qEjqV{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-qEjqVœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}-StructuredOutputComponent-Fk5AM{œfieldNameœ:œllmœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}", - "selected": false, - "source": "OpenAIModel-qEjqV", - "sourceHandle": "{œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-qEjqVœ,œnameœ:œmodel_outputœ,œoutput_typesœ:[œLanguageModelœ]}", - "target": "StructuredOutputComponent-Fk5AM", - "targetHandle": "{œfieldNameœ:œllmœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œLanguageModelœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "StructuredOutputComponent", - "id": "StructuredOutputComponent-Fk5AM", - "name": "structured_output", - "output_types": [ - "Data" - ] - }, - "targetHandle": { - "fieldName": "data", - "id": "ParseData-zFzM6", - "inputTypes": [ - "Data" - ], - "type": "other" - } - }, - "id": "reactflow__edge-StructuredOutputComponent-Fk5AM{œdataTypeœ:œStructuredOutputComponentœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}-ParseData-zFzM6{œfieldNameœ:œdataœ,œidœ:œParseData-zFzM6œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}", - "selected": false, - "source": "StructuredOutputComponent-Fk5AM", - "sourceHandle": "{œdataTypeœ:œStructuredOutputComponentœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œnameœ:œstructured_outputœ,œoutput_typesœ:[œDataœ]}", - "target": "ParseData-zFzM6", - "targetHandle": "{œfieldNameœ:œdataœ,œidœ:œParseData-zFzM6œ,œinputTypesœ:[œDataœ],œtypeœ:œotherœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ParseData", - "id": "ParseData-zFzM6", - "name": "text", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-NJfzg", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ParseData-zFzM6{œdataTypeœ:œParseDataœ,œidœ:œParseData-zFzM6œ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-NJfzg{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-NJfzgœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ParseData-zFzM6", - "sourceHandle": "{œdataTypeœ:œParseDataœ,œidœ:œParseData-zFzM6œ,œnameœ:œtextœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-NJfzg", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-NJfzgœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-N6esY", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-axUVK", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-N6esY{œdataTypeœ:œChatInputœ,œidœ:œChatInput-N6esYœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-axUVK{œfieldNameœ:œinput_valueœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-N6esY", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-N6esYœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-axUVK", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "animated": false, - "className": "", - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-axUVK", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "StructuredOutputComponent-Fk5AM", - "inputTypes": [ - "Message" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Agent-axUVK{œdataTypeœ:œAgentœ,œidœ:œAgent-axUVKœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-StructuredOutputComponent-Fk5AM{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "Agent-axUVK", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-axUVKœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "StructuredOutputComponent-Fk5AM", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œStructuredOutputComponent-Fk5AMœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}" - }, - { - "source": "TavilySearchComponent-J0fu0", - "sourceHandle": "{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-J0fu0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-axUVK", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-axUVK", - "inputTypes": [ - "Tool" - ], - "type": "other" - }, - "sourceHandle": { - "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-J0fu0", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - } + "position": { + "x": 875.7686789989679, + "y": 798.478848045035 }, - "id": "xy-edge__TavilySearchComponent-J0fu0{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-J0fu0œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-axUVK{œfieldNameœ:œtoolsœ,œidœ:œAgent-axUVKœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}" + "selected": true, + "type": "genericNode" } ], "viewport": { 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 1eacdc033d26..0ec923ec6205 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/SaaS Pricing.json @@ -1,5 +1,86 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-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": { @@ -231,6 +312,10 @@ "dragging": false, "height": 693, "id": "Prompt-nzVmM", + "measured": { + "height": 693, + "width": 360 + }, "position": { "x": 1349.861745038984, "y": 347.90475109976467 @@ -241,11 +326,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 693 - } + "width": 320 }, { "data": { @@ -512,6 +593,10 @@ "dragging": false, "height": 234, "id": "ChatOutput-60t7m", + "measured": { + "height": 234, + "width": 360 + }, "position": { "x": 2240.3625274769397, "y": 355.16302699218204 @@ -522,11 +607,7 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 234 - } + "width": 320 }, { "data": { @@ -542,6 +623,10 @@ "dragging": false, "height": 800, "id": "note-BnQHz", + "measured": { + "height": 800, + "width": 328 + }, "position": { "x": 689.7659055360411, "y": 68.95847391680593 @@ -557,11 +642,7 @@ "width": 600 }, "type": "noteNode", - "width": 600, - "measured": { - "width": 328, - "height": 800 - } + "width": 600 }, { "data": { @@ -1127,6 +1208,10 @@ "dragging": false, "height": 650, "id": "Agent-HoULP", + "measured": { + "height": 650, + "width": 360 + }, "position": { "x": 1819.2633856623966, "y": 138.32023808479687 @@ -1137,291 +1222,206 @@ }, "selected": false, "type": "genericNode", - "width": 320, - "measured": { - "width": 360, - "height": 650 - } + "width": 320 }, { - "id": "CalculatorComponent-A0PBx", - "type": "genericNode", - "position": { - "x": 1350.9477037257504, - "y": -45.351578570289234 - }, "data": { + "id": "CalculatorComponent-A0PBx", "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "category": "tools", + "conditional_paths": [], + "custom_fields": {}, + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator", + "documentation": "", + "edited": false, + "field_order": [ + "expression" + ], + "frozen": false, + "icon": "calculator", + "key": "CalculatorComponent", + "legacy": false, + "metadata": {}, + "minimized": false, + "output_types": [], + "outputs": [ + { + "cache": true, + "display_name": "Toolset", + "hidden": null, + "method": "to_toolkit", + "name": "component_as_tool", + "required_inputs": null, + "selected": "Tool", + "types": [ + "Tool" + ], + "value": "__UNDEFINED__" + } + ], + "pinned": false, + "score": 0.001, "template": { "_type": "Component", "code": { - "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, + "fileTypes": [], + "file_path": "", "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, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, "placeholder": "", + "required": true, "show": true, - "name": "expression", - "value": "", - "display_name": "Expression", + "title_case": false, + "type": "code", + "value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom langflow.custom import Component\nfrom langflow.inputs import MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n if isinstance(node, ast.Num): # For backwards compatibility\n if isinstance(node.n, int | float):\n return float(node.n)\n error_msg = f\"Unsupported number type: {type(node.n).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n" + }, + "expression": { + "_input_type": "MessageTextInput", "advanced": false, + "display_name": "Expression", + "dynamic": false, + "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", "input_types": [ "Message" ], - "dynamic": false, - "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "expression", + "placeholder": "", + "required": false, + "show": true, "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, "type": "str", - "_input_type": "MessageTextInput" + "value": "" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "table_icon": "Hammer", + "table_options": { + "block_add": true, + "block_delete": true, + "block_edit": true, + "block_filter": true, + "block_hide": true, + "block_select": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "field_parsers": { + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] + }, + "hide_options": true + }, "table_schema": { "columns": [ { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", "description": "Specify the name of the tool.", "disable_edit": false, + "display_name": "Tool Name", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" }, { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", "description": "Describe the purpose of the tool.", "disable_edit": false, + "display_name": "Tool Description", "edit_mode": "popover", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "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, + "display_name": "Tool Identifiers", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" }, { - "name": "commands", - "display_name": "Commands", - "sortable": false, - "filterable": 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", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "commands", + "sortable": false, + "type": "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." - }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "None-evaluate_expression", "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", + "name": "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" - } - }, - "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": {}, - "category": "tools", - "key": "CalculatorComponent", - "score": 0.001 + } }, "showNode": true, - "type": "CalculatorComponent", - "id": "CalculatorComponent-A0PBx" + "type": "CalculatorComponent" }, - "selected": true, + "dragging": false, + "id": "CalculatorComponent-A0PBx", "measured": { - "width": 360, - "height": 374 + "height": 374, + "width": 360 }, - "dragging": false - } - ], - "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œ}" - }, - { - "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œ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-HoULP", - "inputTypes": [ - "Tool" - ], - "type": "other" - }, - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-A0PBx", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - } + "position": { + "x": 1350.9477037257504, + "y": -45.351578570289234 }, - "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œ}" + "selected": true, + "type": "genericNode" } ], "viewport": { 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 9cfc0eb667a2..7ab989821c65 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Simple Agent.json @@ -1,5 +1,117 @@ { "data": { + "edges": [ + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "ChatInput", + "id": "ChatInput-8EBqM", + "name": "message", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "Agent-rl4Nb", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-8EBqM{œdataTypeœ:œChatInputœ,œidœ:œChatInput-8EBqMœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-rl4Nb{œfieldNameœ:œinput_valueœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "ChatInput-8EBqM", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-8EBqMœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-rl4Nb", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-rl4Nbœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "Agent", + "id": "Agent-rl4Nb", + "name": "response", + "output_types": [ + "Message" + ] + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-f5pzU", + "inputTypes": [ + "Message" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Agent-rl4Nb{œdataTypeœ:œAgentœ,œidœ:œAgent-rl4Nbœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-f5pzU{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-f5pzUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "selected": false, + "source": "Agent-rl4Nb", + "sourceHandle": "{œdataTypeœ: œAgentœ, œidœ: œAgent-rl4Nbœ, œnameœ: œresponseœ, œoutput_typesœ: [œMessageœ]}", + "target": "ChatOutput-f5pzU", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-f5pzUœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "CalculatorComponent", + "id": "CalculatorComponent-lHyX4", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-rl4Nb", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__CalculatorComponent-lHyX4{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-lHyX4œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-rl4Nb{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "CalculatorComponent-lHyX4", + "sourceHandle": "{œdataTypeœ: œCalculatorComponentœ, œidœ: œCalculatorComponent-lHyX4œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-rl4Nb", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-rl4Nbœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + }, + { + "animated": false, + "className": "", + "data": { + "sourceHandle": { + "dataType": "URL", + "id": "URL-vRJK9", + "name": "component_as_tool", + "output_types": [ + "Tool" + ] + }, + "targetHandle": { + "fieldName": "tools", + "id": "Agent-rl4Nb", + "inputTypes": [ + "Tool" + ], + "type": "other" + } + }, + "id": "xy-edge__URL-vRJK9{œdataTypeœ:œURLœ,œidœ:œURL-vRJK9œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-rl4Nb{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "source": "URL-vRJK9", + "sourceHandle": "{œdataTypeœ: œURLœ, œidœ: œURL-vRJK9œ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-rl4Nb", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-rl4Nbœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + } + ], "nodes": [ { "data": { @@ -562,6 +674,7 @@ }, "type": "Agent" }, + "dragging": false, "id": "Agent-rl4Nb", "measured": { "height": 698, @@ -572,8 +685,7 @@ "y": 297.9085084144251 }, "selected": false, - "type": "genericNode", - "dragging": false + "type": "genericNode" }, { "data": { @@ -855,6 +967,7 @@ }, "type": "ChatInput" }, + "dragging": false, "id": "ChatInput-8EBqM", "measured": { "height": 257, @@ -865,8 +978,7 @@ "y": 930.7462715570136 }, "selected": false, - "type": "genericNode", - "dragging": false + "type": "genericNode" }, { "data": { @@ -1144,228 +1256,229 @@ }, { "data": { + "description": "Load and retrive data from specified URLs.", + "display_name": "URL", "id": "URL-vRJK9", "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": { - "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=\"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", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "code", "advanced": true, "dynamic": true, + "fileTypes": [], + "file_path": "", "info": "", + "list": false, "load_from_db": false, - "title_case": false + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "import re\n\nfrom langchain_community.document_loaders import AsyncHtmlLoader, WebBaseLoader\n\nfrom langflow.custom import Component\nfrom langflow.helpers.data import data_to_text\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.schema import Data\nfrom langflow.schema.dataframe import DataFrame\nfrom langflow.schema.message import Message\n\n\nclass URLComponent(Component):\n display_name = \"URL\"\n description = \"Load and retrive data from specified URLs.\"\n icon = \"layout-template\"\n name = \"URL\"\n\n inputs = [\n MessageTextInput(\n name=\"urls\",\n display_name=\"URLs\",\n is_list=True,\n tool_mode=True,\n placeholder=\"Enter a URL...\",\n list_add_label=\"Add URL\",\n ),\n DropdownInput(\n name=\"format\",\n display_name=\"Output Format\",\n info=\"Output Format. Use 'Text' to extract the text from the HTML or 'Raw HTML' for the raw HTML content.\",\n options=[\"Text\", \"Raw HTML\"],\n value=\"Text\",\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"fetch_content\"),\n Output(display_name=\"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" }, "format": { - "tool_mode": false, - "trace_as_metadata": true, + "_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" ], - "combobox": false, - "required": false, "placeholder": "", + "required": false, "show": true, - "name": "format", - "value": "Text", - "display_name": "Output Format", - "advanced": false, - "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, + "tool_mode": false, + "trace_as_metadata": true, "type": "str", - "_input_type": "DropdownInput" + "value": "Text" }, - "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", + "tools_metadata": { + "_input_type": "TableInput", "advanced": false, - "input_types": [ - "Message" - ], + "display_name": "Edit tools", "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_icon": "Hammer", + "table_options": { + "block_add": true, + "block_delete": true, + "block_edit": true, + "block_filter": true, + "block_hide": true, + "block_select": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "field_parsers": { + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] + }, + "hide_options": true + }, "table_schema": { "columns": [ { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", "description": "Specify the name of the tool.", "disable_edit": false, + "display_name": "Tool Name", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" }, { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", "description": "Describe the purpose of the tool.", "disable_edit": false, + "display_name": "Tool Description", "edit_mode": "popover", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "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, + "display_name": "Tool Identifiers", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" }, { - "name": "commands", - "display_name": "Commands", - "sortable": false, - "filterable": 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", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "commands", + "sortable": false, + "type": "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." - }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "URL-fetch_content", "description": "fetch_content() - Load and retrive data from specified URLs.", + "name": "URL-fetch_content", "tags": [ "URL-fetch_content" ] }, { - "name": "URL-fetch_content_text", "description": "fetch_content_text() - Load and retrive data from specified URLs.", + "name": "URL-fetch_content_text", "tags": [ "URL-fetch_content_text" ] }, { - "name": "URL-as_dataframe", "description": "as_dataframe() - Load and retrive data from specified URLs.", + "name": "URL-as_dataframe", "tags": [ "URL-as_dataframe" ] } - ], - "display_name": "Edit tools", + ] + }, + "urls": { + "_input_type": "MessageTextInput", "advanced": false, + "display_name": "URLs", "dynamic": false, "info": "", - "real_time_refresh": true, + "input_types": [ + "Message" + ], + "list": true, + "list_add_label": "Add URL", + "load_from_db": false, + "name": "urls", + "placeholder": "Enter a URL...", + "required": false, + "show": true, "title_case": false, - "type": "table", - "_input_type": "TableInput" + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, + "type": "str", + "value": "" } }, - "description": "Load and retrive data from specified URLs.", - "icon": "layout-template", - "base_classes": [ - "Data", - "DataFrame", - "Message" - ], - "display_name": "URL", - "documentation": "", - "minimized": false, - "custom_fields": {}, - "output_types": [], - "pinned": false, - "conditional_paths": [], - "frozen": false, - "outputs": [ - { - "types": [ - "Tool" - ], - "selected": "Tool", - "name": "component_as_tool", - "hidden": null, - "display_name": "Toolset", - "method": "to_toolkit", - "value": "__UNDEFINED__", - "cache": true, - "required_inputs": null - } - ], - "field_order": [ - "urls", - "format" - ], - "beta": false, - "legacy": false, - "edited": false, - "metadata": {}, - "lf_version": "1.1.1", "tool_mode": true }, - "type": "URL", - "description": "Load and retrive data from specified URLs.", - "display_name": "URL" + "type": "URL" }, + "dragging": false, "id": "URL-vRJK9", "measured": { "height": 453, @@ -1376,8 +1489,7 @@ "y": 27.333577318641687 }, "selected": true, - "type": "genericNode", - "dragging": false + "type": "genericNode" }, { "data": { @@ -1430,316 +1542,204 @@ "type": "noteNode" }, { - "id": "CalculatorComponent-lHyX4", - "type": "genericNode", - "position": { - "x": 1233.166256931297, - "y": 514.7544001650839 - }, "data": { + "id": "CalculatorComponent-lHyX4", "node": { + "base_classes": [ + "Data" + ], + "beta": false, + "category": "tools", + "conditional_paths": [], + "custom_fields": {}, + "description": "Perform basic arithmetic operations on a given expression.", + "display_name": "Calculator", + "documentation": "", + "edited": false, + "field_order": [ + "expression" + ], + "frozen": false, + "icon": "calculator", + "key": "CalculatorComponent", + "legacy": false, + "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, + "score": 0.001, "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, + "fileTypes": [], + "file_path": "", "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, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, "placeholder": "", + "required": true, "show": true, - "name": "expression", - "value": "", - "display_name": "Expression", + "title_case": false, + "type": "code", + "value": "import ast\nimport operator\nfrom collections.abc import Callable\n\nfrom langflow.custom import Component\nfrom langflow.inputs import MessageTextInput\nfrom langflow.io import Output\nfrom langflow.schema import Data\n\n\nclass CalculatorComponent(Component):\n display_name = \"Calculator\"\n description = \"Perform basic arithmetic operations on a given expression.\"\n icon = \"calculator\"\n\n # Cache operators dictionary as a class variable\n OPERATORS: dict[type[ast.operator], Callable] = {\n ast.Add: operator.add,\n ast.Sub: operator.sub,\n ast.Mult: operator.mul,\n ast.Div: operator.truediv,\n ast.Pow: operator.pow,\n }\n\n inputs = [\n MessageTextInput(\n name=\"expression\",\n display_name=\"Expression\",\n info=\"The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').\",\n tool_mode=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"result\", type_=Data, method=\"evaluate_expression\"),\n ]\n\n def _eval_expr(self, node: ast.AST) -> float:\n \"\"\"Evaluate an AST node recursively.\"\"\"\n if isinstance(node, ast.Constant):\n if isinstance(node.value, int | float):\n return float(node.value)\n error_msg = f\"Unsupported constant type: {type(node.value).__name__}\"\n raise TypeError(error_msg)\n if isinstance(node, ast.Num): # For backwards compatibility\n if isinstance(node.n, int | float):\n return float(node.n)\n error_msg = f\"Unsupported number type: {type(node.n).__name__}\"\n raise TypeError(error_msg)\n\n if isinstance(node, ast.BinOp):\n op_type = type(node.op)\n if op_type not in self.OPERATORS:\n error_msg = f\"Unsupported binary operator: {op_type.__name__}\"\n raise TypeError(error_msg)\n\n left = self._eval_expr(node.left)\n right = self._eval_expr(node.right)\n return self.OPERATORS[op_type](left, right)\n\n error_msg = f\"Unsupported operation or expression type: {type(node).__name__}\"\n raise TypeError(error_msg)\n\n def evaluate_expression(self) -> Data:\n \"\"\"Evaluate the mathematical expression and return the result.\"\"\"\n try:\n tree = ast.parse(self.expression, mode=\"eval\")\n result = self._eval_expr(tree.body)\n\n formatted_result = f\"{float(result):.6f}\".rstrip(\"0\").rstrip(\".\")\n self.log(f\"Calculation result: {formatted_result}\")\n\n self.status = formatted_result\n return Data(data={\"result\": formatted_result})\n\n except ZeroDivisionError:\n error_message = \"Error: Division by zero\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n except (SyntaxError, TypeError, KeyError, ValueError, AttributeError, OverflowError) as e:\n error_message = f\"Invalid expression: {e!s}\"\n self.status = error_message\n return Data(data={\"error\": error_message, \"input\": self.expression})\n\n def build(self):\n \"\"\"Return the main evaluation function.\"\"\"\n return self.evaluate_expression\n" + }, + "expression": { + "_input_type": "MessageTextInput", "advanced": false, + "display_name": "Expression", + "dynamic": false, + "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", "input_types": [ "Message" ], - "dynamic": false, - "info": "The arithmetic expression to evaluate (e.g., '4*4*(33/22)+12-20').", + "list": false, + "list_add_label": "Add More", + "load_from_db": false, + "name": "expression", + "placeholder": "", + "required": false, + "show": true, "title_case": false, + "tool_mode": true, + "trace_as_input": true, + "trace_as_metadata": true, "type": "str", - "_input_type": "MessageTextInput" + "value": "" }, "tools_metadata": { - "tool_mode": false, + "_input_type": "TableInput", + "advanced": false, + "display_name": "Edit tools", + "dynamic": false, + "info": "", "is_list": true, "list_add_label": "Add More", + "name": "tools_metadata", + "placeholder": "", + "real_time_refresh": true, + "required": false, + "show": true, + "table_icon": "Hammer", + "table_options": { + "block_add": true, + "block_delete": true, + "block_edit": true, + "block_filter": true, + "block_hide": true, + "block_select": true, + "block_sort": true, + "description": "Modify tool names and descriptions to help agents understand when to use each tool.", + "field_parsers": { + "commands": "commands", + "name": [ + "snake_case", + "no_blank" + ] + }, + "hide_options": true + }, "table_schema": { "columns": [ { - "name": "name", - "display_name": "Tool Name", - "sortable": false, - "filterable": false, - "type": "text", "description": "Specify the name of the tool.", "disable_edit": false, + "display_name": "Tool Name", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "name", + "sortable": false, + "type": "text" }, { - "name": "description", - "display_name": "Tool Description", - "sortable": false, - "filterable": false, - "type": "text", "description": "Describe the purpose of the tool.", "disable_edit": false, + "display_name": "Tool Description", "edit_mode": "popover", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "description", + "sortable": false, + "type": "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, + "display_name": "Tool Identifiers", "edit_mode": "inline", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "tags", + "sortable": false, + "type": "text" }, { - "name": "commands", - "display_name": "Commands", - "sortable": false, - "filterable": 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", - "formatter": "text" + "filterable": false, + "formatter": "text", + "name": "commands", + "sortable": false, + "type": "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." - }, + "title_case": false, + "tool_mode": false, "trace_as_metadata": true, - "required": false, - "placeholder": "", - "show": true, - "name": "tools_metadata", + "trigger_icon": "Hammer", + "trigger_text": "", + "type": "table", "value": [ { - "name": "None-evaluate_expression", "description": "evaluate_expression() - Perform basic arithmetic operations on a given expression.", + "name": "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" + ] } - }, - "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": {}, - "category": "tools", - "key": "CalculatorComponent", - "score": 0.001, - "lf_version": "1.1.1" + } }, "showNode": true, - "type": "CalculatorComponent", - "id": "CalculatorComponent-lHyX4" + "type": "CalculatorComponent" }, - "selected": false, + "dragging": false, + "id": "CalculatorComponent-lHyX4", "measured": { - "width": 360, - "height": 374 - }, - "dragging": false - } - ], - "edges": [ - { - "data": { - "sourceHandle": { - "dataType": "ChatInput", - "id": "ChatInput-8EBqM", - "name": "message", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "Agent-rl4Nb", - "inputTypes": [ - "Message" - ], - "type": "str" - } + "height": 374, + "width": 360 }, - "id": "reactflow__edge-ChatInput-8EBqM{œdataTypeœ:œChatInputœ,œidœ:œChatInput-8EBqMœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-rl4Nb{œfieldNameœ:œinput_valueœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-8EBqM", - "sourceHandle": "{œdataTypeœ:œChatInputœ,œidœ:œChatInput-8EBqMœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}", - "target": "Agent-rl4Nb", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "className": "", - "animated": false - }, - { - "data": { - "sourceHandle": { - "dataType": "Agent", - "id": "Agent-rl4Nb", - "name": "response", - "output_types": [ - "Message" - ] - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-f5pzU", - "inputTypes": [ - "Message" - ], - "type": "str" - } + "position": { + "x": 1233.166256931297, + "y": 514.7544001650839 }, - "id": "reactflow__edge-Agent-rl4Nb{œdataTypeœ:œAgentœ,œidœ:œAgent-rl4Nbœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}-ChatOutput-f5pzU{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-f5pzUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "Agent-rl4Nb", - "sourceHandle": "{œdataTypeœ:œAgentœ,œidœ:œAgent-rl4Nbœ,œnameœ:œresponseœ,œoutput_typesœ:[œMessageœ]}", - "target": "ChatOutput-f5pzU", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-f5pzUœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", - "className": "", - "animated": false - }, - { - "source": "CalculatorComponent-lHyX4", - "sourceHandle": "{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-lHyX4œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-rl4Nb", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-rl4Nb", - "inputTypes": [ - "Tool" - ], - "type": "other" - }, - "sourceHandle": { - "dataType": "CalculatorComponent", - "id": "CalculatorComponent-lHyX4", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - } - }, - "id": "xy-edge__CalculatorComponent-lHyX4{œdataTypeœ:œCalculatorComponentœ,œidœ:œCalculatorComponent-lHyX4œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-rl4Nb{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "animated": false, - "className": "" - }, - { - "source": "URL-vRJK9", - "sourceHandle": "{œdataTypeœ:œURLœ,œidœ:œURL-vRJK9œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}", - "target": "Agent-rl4Nb", - "targetHandle": "{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "data": { - "targetHandle": { - "fieldName": "tools", - "id": "Agent-rl4Nb", - "inputTypes": [ - "Tool" - ], - "type": "other" - }, - "sourceHandle": { - "dataType": "URL", - "id": "URL-vRJK9", - "name": "component_as_tool", - "output_types": [ - "Tool" - ] - } - }, - "id": "xy-edge__URL-vRJK9{œdataTypeœ:œURLœ,œidœ:œURL-vRJK9œ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-rl4Nb{œfieldNameœ:œtoolsœ,œidœ:œAgent-rl4Nbœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", - "animated": false, - "className": "" + "type": "genericNode" } ], "viewport": {