From 2dfdb9f701410b29317daa598ed792073dc1848d Mon Sep 17 00:00:00 2001 From: Sergey Ryabov <944361+colriot@users.noreply.github.com> Date: Fri, 14 Mar 2025 16:31:35 +0000 Subject: [PATCH] feat: Update AgentQL integration with new features (#7089) * feat: Update AgentQL integration with new features * Update templates * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Edwin Jose --- .../components/agentql/agentql_api.py | 64 +++-- .../starter_projects/News Aggregator.json | 199 ++++++++++++---- .../starter_projects/Price Deal Finder.json | 219 +++++++++++++----- 3 files changed, 355 insertions(+), 127 deletions(-) diff --git a/src/backend/base/langflow/components/agentql/agentql_api.py b/src/backend/base/langflow/components/agentql/agentql_api.py index 33c36acd5..51377be44 100644 --- a/src/backend/base/langflow/components/agentql/agentql_api.py +++ b/src/backend/base/langflow/components/agentql/agentql_api.py @@ -2,8 +2,10 @@ import httpx from loguru import logger from langflow.custom import Component +from langflow.field_typing.range_spec import RangeSpec from langflow.io import ( - DictInput, + BoolInput, + DropdownInput, IntInput, MessageTextInput, MultilineInput, @@ -49,24 +51,48 @@ class AgentQL(Component): info="A Natural Language description of the data to extract from the page. Alternative to AgentQL query.", tool_mode=True, ), + BoolInput( + name="is_stealth_mode_enabled", + display_name="Enable Stealth Mode (Beta)", + info="Enable experimental anti-bot evasion strategies. May not work for all websites at all times.", + value=False, + advanced=True, + ), IntInput( name="timeout", display_name="Timeout", - info="Timeout in seconds for the request. Increase if data extraction takes too long.", + info="Seconds to wait for a request.", value=900, advanced=True, ), - DictInput( - name="params", - display_name="Additional Params", - info="The additional params to send with the request. For details refer to https://docs.agentql.com/rest-api/api-reference#request-body.", - is_list=True, - value={ - "mode": "fast", - "wait_for": 0, - "is_scroll_to_bottom_enabled": False, - "is_screenshot_enabled": False, - }, + DropdownInput( + name="mode", + display_name="Request Mode", + info="'standard' uses deep data analysis, while 'fast' trades some depth of analysis for speed.", + options=["fast", "standard"], + value="fast", + advanced=True, + ), + IntInput( + name="wait_for", + display_name="Wait For", + info="Seconds to wait for the page to load before extracting data.", + value=0, + range_spec=RangeSpec(min=0, max=10, step_type="int"), + advanced=True, + ), + BoolInput( + name="is_scroll_to_bottom_enabled", + display_name="Enable scroll to bottom", + info="Scroll to bottom of the page before extracting data.", + value=False, + advanced=True, + ), + BoolInput( + name="is_screenshot_enabled", + display_name="Enable screenshot", + info="Take a screenshot before extracting data. Returned in 'metadata' as a Base64 string.", + value=False, advanced=True, ), ] @@ -87,7 +113,15 @@ class AgentQL(Component): "url": self.url, "query": self.query, "prompt": self.prompt, - "params": self.params, + "params": { + "mode": self.mode, + "wait_for": self.wait_for, + "is_scroll_to_bottom_enabled": self.is_scroll_to_bottom_enabled, + "is_screenshot_enabled": self.is_screenshot_enabled, + }, + "metadata": { + "experimental_stealth_mode_enabled": self.is_stealth_mode_enabled, + }, } if not self.prompt and not self.query: @@ -106,7 +140,7 @@ class AgentQL(Component): except httpx.HTTPStatusError as e: response = e.response - if response.status_code in {401, 403}: + if response.status_code == httpx.codes.UNAUTHORIZED: self.status = "Please, provide a valid API Key. You can create one at https://dev.agentql.com." else: try: diff --git a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json index 823a0b4b4..a53d71daf 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/News Aggregator.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "AgentQL", - "id": "AgentQL-XIw0m", + "id": "AgentQL-mvSyT", "name": "component_as_tool", "output_types": [ "Tool" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-O1xzr", + "id": "Agent-0WtsM", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-AgentQL-XIw0m{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-XIw0mœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-O1xzr{œfieldNameœ:œtoolsœ,œidœ:œAgent-O1xzrœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-AgentQL-mvSyT{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-mvSyTœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-0WtsM{œfieldNameœ:œtoolsœ,œidœ:œAgent-0WtsMœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "AgentQL-XIw0m", - "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-XIw0mœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-O1xzr", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-O1xzrœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "AgentQL-mvSyT", + "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-mvSyTœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-0WtsM", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-0WtsMœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-KdiYi", + "id": "ChatInput-aQctf", "name": "message", "output_types": [ "Message" @@ -43,25 +43,25 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-O1xzr", + "id": "Agent-0WtsM", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-KdiYi{œdataTypeœ:œChatInputœ,œidœ:œChatInput-KdiYiœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-O1xzr{œfieldNameœ:œinput_valueœ,œidœ:œAgent-O1xzrœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-aQctf{œdataTypeœ:œChatInputœ,œidœ:œChatInput-aQctfœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-0WtsM{œfieldNameœ:œinput_valueœ,œidœ:œAgent-0WtsMœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-KdiYi", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-KdiYiœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-O1xzr", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-O1xzrœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-aQctf", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-aQctfœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-0WtsM", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-0WtsMœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ { "data": { - "id": "note-vGF5M", + "id": "note-ha8Ib", "node": { "description": "### 💡 Add your OpenAI API key here", "display_name": "", @@ -73,7 +73,7 @@ "type": "note" }, "dragging": false, - "id": "note-vGF5M", + "id": "note-ha8Ib", "measured": { "height": 324, "width": 324 @@ -87,7 +87,7 @@ }, { "data": { - "id": "note-VvhWf", + "id": "note-RBW3I", "node": { "description": "### 💡 Add your AgentQL API key here", "display_name": "", @@ -100,7 +100,7 @@ }, "dragging": false, "height": 346, - "id": "note-VvhWf", + "id": "note-RBW3I", "measured": { "height": 346, "width": 324 @@ -116,7 +116,7 @@ "data": { "description": "Uses AgentQL API to extract structured data from a given URL.", "display_name": "AgentQL Query Data", - "id": "AgentQL-XIw0m", + "id": "AgentQL-mvSyT", "node": { "base_classes": [ "Data" @@ -133,8 +133,12 @@ "url", "query", "prompt", + "is_stealth_mode_enabled", "timeout", - "params" + "mode", + "wait_for", + "is_scroll_to_bottom_enabled", + "is_screenshot_enabled" ], "frozen": false, "icon": "AgentQL", @@ -171,7 +175,7 @@ "input_types": [ "Message" ], - "load_from_db": true, + "load_from_db": false, "name": "api_key", "password": true, "placeholder": "", @@ -197,34 +201,89 @@ "show": true, "title_case": false, "type": "code", - "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.io import (\n DictInput,\n IntInput,\n MessageTextInput,\n MultilineInput,\n Output,\n SecretStrInput,\n)\nfrom langflow.schema import Data\n\n\nclass AgentQL(Component):\n display_name = \"Extract Web Data\"\n description = \"Extracts structured data from a web page using an AgentQL query or a Natural Language description.\"\n documentation: str = \"https://docs.agentql.com/rest-api/api-reference\"\n icon = \"AgentQL\"\n name = \"AgentQL\"\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n required=True,\n password=True,\n info=\"Your AgentQL API key from dev.agentql.com\",\n ),\n MessageTextInput(\n name=\"url\",\n display_name=\"URL\",\n required=True,\n info=\"The URL of the public web page you want to extract data from.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"query\",\n display_name=\"AgentQL Query\",\n required=False,\n info=\"The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"prompt\",\n display_name=\"Prompt\",\n required=False,\n info=\"A Natural Language description of the data to extract from the page. Alternative to AgentQL query.\",\n tool_mode=True,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"Timeout in seconds for the request. Increase if data extraction takes too long.\",\n value=900,\n advanced=True,\n ),\n DictInput(\n name=\"params\",\n display_name=\"Additional Params\",\n info=\"The additional params to send with the request. For details refer to https://docs.agentql.com/rest-api/api-reference#request-body.\",\n is_list=True,\n value={\n \"mode\": \"fast\",\n \"wait_for\": 0,\n \"is_scroll_to_bottom_enabled\": False,\n \"is_screenshot_enabled\": False,\n },\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"build_output\"),\n ]\n\n def build_output(self) -> Data:\n endpoint = \"https://api.agentql.com/v1/query-data\"\n headers = {\n \"X-API-Key\": self.api_key,\n \"Content-Type\": \"application/json\",\n \"X-TF-Request-Origin\": \"langflow\",\n }\n\n payload = {\n \"url\": self.url,\n \"query\": self.query,\n \"prompt\": self.prompt,\n \"params\": self.params,\n }\n\n if not self.prompt and not self.query:\n self.status = \"Either Query or Prompt must be provided.\"\n raise ValueError(self.status)\n if self.prompt and self.query:\n self.status = \"Both Query and Prompt can't be provided at the same time.\"\n raise ValueError(self.status)\n\n try:\n response = httpx.post(endpoint, headers=headers, json=payload, timeout=self.timeout)\n response.raise_for_status()\n\n json = response.json()\n data = Data(result=json[\"data\"], metadata=json[\"metadata\"])\n\n except httpx.HTTPStatusError as e:\n response = e.response\n if response.status_code in {401, 403}:\n self.status = \"Please, provide a valid API Key. You can create one at https://dev.agentql.com.\"\n else:\n try:\n error_json = response.json()\n logger.error(\n f\"Failure response: '{response.status_code} {response.reason_phrase}' with body: {error_json}\"\n )\n msg = error_json[\"error_info\"] if \"error_info\" in error_json else error_json[\"detail\"]\n except (ValueError, TypeError):\n msg = f\"HTTP {e}.\"\n self.status = msg\n raise ValueError(self.status) from e\n\n else:\n self.status = data\n return data\n" + "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n IntInput,\n MessageTextInput,\n MultilineInput,\n Output,\n SecretStrInput,\n)\nfrom langflow.schema import Data\n\n\nclass AgentQL(Component):\n display_name = \"Extract Web Data\"\n description = \"Extracts structured data from a web page using an AgentQL query or a Natural Language description.\"\n documentation: str = \"https://docs.agentql.com/rest-api/api-reference\"\n icon = \"AgentQL\"\n name = \"AgentQL\"\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n required=True,\n password=True,\n info=\"Your AgentQL API key from dev.agentql.com\",\n ),\n MessageTextInput(\n name=\"url\",\n display_name=\"URL\",\n required=True,\n info=\"The URL of the public web page you want to extract data from.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"query\",\n display_name=\"AgentQL Query\",\n required=False,\n info=\"The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"prompt\",\n display_name=\"Prompt\",\n required=False,\n info=\"A Natural Language description of the data to extract from the page. Alternative to AgentQL query.\",\n tool_mode=True,\n ),\n BoolInput(\n name=\"is_stealth_mode_enabled\",\n display_name=\"Enable Stealth Mode (Beta)\",\n info=\"Enable experimental anti-bot evasion strategies. May not work for all websites at all times.\",\n value=False,\n advanced=True,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"Seconds to wait for a request.\",\n value=900,\n advanced=True,\n ),\n DropdownInput(\n name=\"mode\",\n display_name=\"Request Mode\",\n info=\"'standard' uses deep data analysis, while 'fast' trades some depth of analysis for speed.\",\n options=[\"fast\", \"standard\"],\n value=\"fast\",\n advanced=True,\n ),\n IntInput(\n name=\"wait_for\",\n display_name=\"Wait For\",\n info=\"Seconds to wait for the page to load before extracting data.\",\n value=0,\n range_spec=RangeSpec(min=0, max=10, step_type=\"int\"),\n advanced=True,\n ),\n BoolInput(\n name=\"is_scroll_to_bottom_enabled\",\n display_name=\"Enable scroll to bottom\",\n info=\"Scroll to bottom of the page before extracting data.\",\n value=False,\n advanced=True,\n ),\n BoolInput(\n name=\"is_screenshot_enabled\",\n display_name=\"Enable screenshot\",\n info=\"Take a screenshot before extracting data. Returned in 'metadata' as a Base64 string.\",\n value=False,\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"build_output\"),\n ]\n\n def build_output(self) -> Data:\n endpoint = \"https://api.agentql.com/v1/query-data\"\n headers = {\n \"X-API-Key\": self.api_key,\n \"Content-Type\": \"application/json\",\n \"X-TF-Request-Origin\": \"langflow\",\n }\n\n payload = {\n \"url\": self.url,\n \"query\": self.query,\n \"prompt\": self.prompt,\n \"params\": {\n \"mode\": self.mode,\n \"wait_for\": self.wait_for,\n \"is_scroll_to_bottom_enabled\": self.is_scroll_to_bottom_enabled,\n \"is_screenshot_enabled\": self.is_screenshot_enabled,\n },\n \"metadata\": {\n \"experimental_stealth_mode_enabled\": self.is_stealth_mode_enabled,\n },\n }\n\n if not self.prompt and not self.query:\n self.status = \"Either Query or Prompt must be provided.\"\n raise ValueError(self.status)\n if self.prompt and self.query:\n self.status = \"Both Query and Prompt can't be provided at the same time.\"\n raise ValueError(self.status)\n\n try:\n response = httpx.post(endpoint, headers=headers, json=payload, timeout=self.timeout)\n response.raise_for_status()\n\n json = response.json()\n data = Data(result=json[\"data\"], metadata=json[\"metadata\"])\n\n except httpx.HTTPStatusError as e:\n response = e.response\n if response.status_code == httpx.codes.UNAUTHORIZED:\n self.status = \"Please, provide a valid API Key. You can create one at https://dev.agentql.com.\"\n else:\n try:\n error_json = response.json()\n logger.error(\n f\"Failure response: '{response.status_code} {response.reason_phrase}' with body: {error_json}\"\n )\n msg = error_json[\"error_info\"] if \"error_info\" in error_json else error_json[\"detail\"]\n except (ValueError, TypeError):\n msg = f\"HTTP {e}.\"\n self.status = msg\n raise ValueError(self.status) from e\n\n else:\n self.status = data\n return data\n" }, - "params": { - "_input_type": "DictInput", + "is_screenshot_enabled": { + "_input_type": "BoolInput", "advanced": true, - "display_name": "Additional Params", + "display_name": "Enable screenshot", "dynamic": false, - "info": "The additional params to send with the request. For details refer to https://docs.agentql.com/rest-api/api-reference#request-body.", - "list": true, + "info": "Take a screenshot before extracting data. Returned in 'metadata' as a Base64 string.", + "list": false, "list_add_label": "Add More", - "name": "params", + "name": "is_screenshot_enabled", "placeholder": "", "required": false, "show": true, "title_case": false, "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": { - "is_screenshot_enabled": false, - "is_scroll_to_bottom_enabled": false, - "mode": "fast", - "wait_for": 0 - } + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "is_scroll_to_bottom_enabled": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Enable scroll to bottom", + "dynamic": false, + "info": "Scroll to bottom of the page before extracting data.", + "list": false, + "list_add_label": "Add More", + "name": "is_scroll_to_bottom_enabled", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "is_stealth_mode_enabled": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Enable Stealth Mode (Beta)", + "dynamic": false, + "info": "Enable experimental anti-bot evasion strategies. May not work for all websites at all times.", + "list": false, + "list_add_label": "Add More", + "name": "is_stealth_mode_enabled", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "mode": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Request Mode", + "dynamic": false, + "info": "'standard' uses deep data analysis, while 'fast' trades some depth of analysis for speed.", + "name": "mode", + "options": [ + "fast", + "standard" + ], + "options_metadata": [], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "fast" }, "prompt": { "_input_type": "MultilineInput", "advanced": false, + "copy_field": false, "display_name": "Prompt", "dynamic": false, "info": "A Natural Language description of the data to extract from the page. Alternative to AgentQL query.", @@ -249,6 +308,7 @@ "query": { "_input_type": "MultilineInput", "advanced": false, + "copy_field": false, "display_name": "AgentQL Query", "dynamic": false, "info": "The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.", @@ -275,7 +335,7 @@ "advanced": true, "display_name": "Timeout", "dynamic": false, - "info": "Timeout in seconds for the request. Increase if data extraction takes too long.", + "info": "Seconds to wait for a request.", "list": false, "list_add_label": "Add More", "name": "timeout", @@ -360,6 +420,19 @@ "name": "tags", "sortable": false, "type": "str" + }, + { + "default": true, + "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", + "disable_edit": false, + "display_name": "Enable", + "edit_mode": "popover", + "filterable": true, + "formatter": "boolean", + "hidden": false, + "name": "status", + "sortable": true, + "type": "boolean" } ] }, @@ -373,6 +446,7 @@ { "description": "build_output(api_key: Message, url: Message) - Extracts structured data from a web page using an AgentQL query or a Natural Language description.", "name": "AgentQL-build_output", + "status": true, "tags": [ "AgentQL-build_output" ] @@ -401,6 +475,30 @@ "trace_as_metadata": true, "type": "str", "value": "" + }, + "wait_for": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Wait For", + "dynamic": false, + "info": "Seconds to wait for the page to load before extracting data.", + "list": false, + "list_add_label": "Add More", + "name": "wait_for", + "placeholder": "", + "range_spec": { + "max": 10, + "min": 0, + "step": 0.1, + "step_type": "int" + }, + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 0 } }, "tool_mode": true @@ -409,7 +507,7 @@ "type": "AgentQL" }, "dragging": false, - "id": "AgentQL-XIw0m", + "id": "AgentQL-mvSyT", "measured": { "height": 599, "width": 320 @@ -423,7 +521,7 @@ }, { "data": { - "id": "ChatInput-KdiYi", + "id": "ChatInput-aQctf", "node": { "base_classes": [ "Message" @@ -720,7 +818,7 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-KdiYi", + "id": "ChatInput-aQctf", "measured": { "height": 66, "width": 192 @@ -734,7 +832,7 @@ }, { "data": { - "id": "ChatOutput-QiEpu", + "id": "ChatOutput-yNdUZ", "node": { "base_classes": [ "Message" @@ -1026,7 +1124,7 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-QiEpu", + "id": "ChatOutput-yNdUZ", "measured": { "height": 66, "width": 192 @@ -1040,7 +1138,7 @@ }, { "data": { - "id": "Agent-O1xzr", + "id": "Agent-0WtsM", "node": { "base_classes": [ "Message" @@ -1716,7 +1814,7 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-O1xzr", + "id": "Agent-0WtsM", "measured": { "height": 621, "width": 320 @@ -1730,7 +1828,7 @@ }, { "data": { - "id": "note-OAlDJ", + "id": "note-X9QDV", "node": { "description": "# News Aggregator\n\nThis flow extracts structured data from a URL.\n## Prerequisites\n\n* **[AgentQL API Key](https://dev.agentql.com/api-keys)**\n* **[OpenAI API Key](https://platform.openai.com/)**\n\n## Quick Start\n\n1. Add your [AgentQL API Key](https://dev.agentql.com/api-keys) to the **AgentQL** component.\n2. Add your [OpenAI API Key](https://platform.openai.com/) to the **Agent** component.\n3. Click **Playground** and enter a question.\nThe **Agent** component populates the **Agent QL** component's **URL** and **Query** fields, and returns a structured response to your question.", "display_name": "", @@ -1742,7 +1840,7 @@ "type": "note" }, "dragging": false, - "id": "note-OAlDJ", + "id": "note-X9QDV", "measured": { "height": 604, "width": 325 @@ -1756,18 +1854,17 @@ } ], "viewport": { - "x": -140.6486665710372, - "y": 68.92081829746667, - "zoom": 1.0230031993478927 + "x": -122.32493574893215, + "y": 249.0480899983669, + "zoom": 0.8862607313804116 } }, "description": "Extracts data and information from webpages.", "endpoint_name": null, - "id": "a5383bea-acb4-44ba-adeb-80c0fcb168b9", + "id": "ed796384-2002-49d5-8480-8c8aa806c9d5", "is_component": false, "last_tested_version": "1.2.0", "name": "News Aggregator", - "icon": "Newspaper", "tags": [ "web-scraping", "agents" diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json index 1dc455b07..a8ed08159 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Price Deal Finder.json @@ -7,7 +7,7 @@ "data": { "sourceHandle": { "dataType": "AgentQL", - "id": "AgentQL-R0YLG", + "id": "AgentQL-7RVLY", "name": "component_as_tool", "output_types": [ "Tool" @@ -15,19 +15,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-7PMCu", + "id": "Agent-O0yDh", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-AgentQL-R0YLG{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-R0YLGœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-7PMCu{œfieldNameœ:œtoolsœ,œidœ:œAgent-7PMCuœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-AgentQL-7RVLY{œdataTypeœ:œAgentQLœ,œidœ:œAgentQL-7RVLYœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-O0yDh{œfieldNameœ:œtoolsœ,œidœ:œAgent-O0yDhœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "AgentQL-R0YLG", - "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-R0YLGœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-7PMCu", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-7PMCuœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "AgentQL-7RVLY", + "sourceHandle": "{œdataTypeœ: œAgentQLœ, œidœ: œAgentQL-7RVLYœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-O0yDh", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-O0yDhœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -35,7 +35,7 @@ "data": { "sourceHandle": { "dataType": "TavilySearchComponent", - "id": "TavilySearchComponent-K4joL", + "id": "TavilySearchComponent-Wm5fh", "name": "component_as_tool", "output_types": [ "Tool" @@ -43,19 +43,19 @@ }, "targetHandle": { "fieldName": "tools", - "id": "Agent-7PMCu", + "id": "Agent-O0yDh", "inputTypes": [ "Tool" ], "type": "other" } }, - "id": "reactflow__edge-TavilySearchComponent-K4joL{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-K4joLœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-7PMCu{œfieldNameœ:œtoolsœ,œidœ:œAgent-7PMCuœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", + "id": "reactflow__edge-TavilySearchComponent-Wm5fh{œdataTypeœ:œTavilySearchComponentœ,œidœ:œTavilySearchComponent-Wm5fhœ,œnameœ:œcomponent_as_toolœ,œoutput_typesœ:[œToolœ]}-Agent-O0yDh{œfieldNameœ:œtoolsœ,œidœ:œAgent-O0yDhœ,œinputTypesœ:[œToolœ],œtypeœ:œotherœ}", "selected": false, - "source": "TavilySearchComponent-K4joL", - "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-K4joLœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", - "target": "Agent-7PMCu", - "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-7PMCuœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" + "source": "TavilySearchComponent-Wm5fh", + "sourceHandle": "{œdataTypeœ: œTavilySearchComponentœ, œidœ: œTavilySearchComponent-Wm5fhœ, œnameœ: œcomponent_as_toolœ, œoutput_typesœ: [œToolœ]}", + "target": "Agent-O0yDh", + "targetHandle": "{œfieldNameœ: œtoolsœ, œidœ: œAgent-O0yDhœ, œinputTypesœ: [œToolœ], œtypeœ: œotherœ}" }, { "animated": false, @@ -63,7 +63,7 @@ "data": { "sourceHandle": { "dataType": "ChatInput", - "id": "ChatInput-M0lPa", + "id": "ChatInput-JghTQ", "name": "message", "output_types": [ "Message" @@ -71,25 +71,25 @@ }, "targetHandle": { "fieldName": "input_value", - "id": "Agent-7PMCu", + "id": "Agent-O0yDh", "inputTypes": [ "Message" ], "type": "str" } }, - "id": "reactflow__edge-ChatInput-M0lPa{œdataTypeœ:œChatInputœ,œidœ:œChatInput-M0lPaœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-7PMCu{œfieldNameœ:œinput_valueœ,œidœ:œAgent-7PMCuœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", + "id": "reactflow__edge-ChatInput-JghTQ{œdataTypeœ:œChatInputœ,œidœ:œChatInput-JghTQœ,œnameœ:œmessageœ,œoutput_typesœ:[œMessageœ]}-Agent-O0yDh{œfieldNameœ:œinput_valueœ,œidœ:œAgent-O0yDhœ,œinputTypesœ:[œMessageœ],œtypeœ:œstrœ}", "selected": false, - "source": "ChatInput-M0lPa", - "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-M0lPaœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", - "target": "Agent-7PMCu", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-7PMCuœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" + "source": "ChatInput-JghTQ", + "sourceHandle": "{œdataTypeœ: œChatInputœ, œidœ: œChatInput-JghTQœ, œnameœ: œmessageœ, œoutput_typesœ: [œMessageœ]}", + "target": "Agent-O0yDh", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œAgent-O0yDhœ, œinputTypesœ: [œMessageœ], œtypeœ: œstrœ}" } ], "nodes": [ { "data": { - "id": "ChatInput-M0lPa", + "id": "ChatInput-JghTQ", "node": { "base_classes": [ "Message" @@ -386,7 +386,7 @@ "type": "ChatInput" }, "dragging": false, - "id": "ChatInput-M0lPa", + "id": "ChatInput-JghTQ", "measured": { "height": 66, "width": 192 @@ -400,7 +400,7 @@ }, { "data": { - "id": "ChatOutput-LyZb7", + "id": "ChatOutput-HVvix", "node": { "base_classes": [ "Message" @@ -692,7 +692,7 @@ "type": "ChatOutput" }, "dragging": false, - "id": "ChatOutput-LyZb7", + "id": "ChatOutput-HVvix", "measured": { "height": 66, "width": 192 @@ -706,7 +706,7 @@ }, { "data": { - "id": "TavilySearchComponent-K4joL", + "id": "TavilySearchComponent-Wm5fh", "node": { "base_classes": [ "Data", @@ -1039,7 +1039,7 @@ "type": "TavilySearchComponent" }, "dragging": false, - "id": "TavilySearchComponent-K4joL", + "id": "TavilySearchComponent-Wm5fh", "measured": { "height": 435, "width": 320 @@ -1055,7 +1055,7 @@ "data": { "description": "Uses AgentQL API to extract structured data from a given URL.", "display_name": "AgentQL Query Data", - "id": "AgentQL-R0YLG", + "id": "AgentQL-7RVLY", "node": { "base_classes": [ "Data" @@ -1072,8 +1072,12 @@ "url", "query", "prompt", + "is_stealth_mode_enabled", "timeout", - "params" + "mode", + "wait_for", + "is_scroll_to_bottom_enabled", + "is_screenshot_enabled" ], "frozen": false, "icon": "AgentQL", @@ -1136,34 +1140,89 @@ "show": true, "title_case": false, "type": "code", - "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.io import (\n DictInput,\n IntInput,\n MessageTextInput,\n MultilineInput,\n Output,\n SecretStrInput,\n)\nfrom langflow.schema import Data\n\n\nclass AgentQL(Component):\n display_name = \"Extract Web Data\"\n description = \"Extracts structured data from a web page using an AgentQL query or a Natural Language description.\"\n documentation: str = \"https://docs.agentql.com/rest-api/api-reference\"\n icon = \"AgentQL\"\n name = \"AgentQL\"\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n required=True,\n password=True,\n info=\"Your AgentQL API key from dev.agentql.com\",\n ),\n MessageTextInput(\n name=\"url\",\n display_name=\"URL\",\n required=True,\n info=\"The URL of the public web page you want to extract data from.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"query\",\n display_name=\"AgentQL Query\",\n required=False,\n info=\"The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"prompt\",\n display_name=\"Prompt\",\n required=False,\n info=\"A Natural Language description of the data to extract from the page. Alternative to AgentQL query.\",\n tool_mode=True,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"Timeout in seconds for the request. Increase if data extraction takes too long.\",\n value=900,\n advanced=True,\n ),\n DictInput(\n name=\"params\",\n display_name=\"Additional Params\",\n info=\"The additional params to send with the request. For details refer to https://docs.agentql.com/rest-api/api-reference#request-body.\",\n is_list=True,\n value={\n \"mode\": \"fast\",\n \"wait_for\": 0,\n \"is_scroll_to_bottom_enabled\": False,\n \"is_screenshot_enabled\": False,\n },\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"build_output\"),\n ]\n\n def build_output(self) -> Data:\n endpoint = \"https://api.agentql.com/v1/query-data\"\n headers = {\n \"X-API-Key\": self.api_key,\n \"Content-Type\": \"application/json\",\n \"X-TF-Request-Origin\": \"langflow\",\n }\n\n payload = {\n \"url\": self.url,\n \"query\": self.query,\n \"prompt\": self.prompt,\n \"params\": self.params,\n }\n\n if not self.prompt and not self.query:\n self.status = \"Either Query or Prompt must be provided.\"\n raise ValueError(self.status)\n if self.prompt and self.query:\n self.status = \"Both Query and Prompt can't be provided at the same time.\"\n raise ValueError(self.status)\n\n try:\n response = httpx.post(endpoint, headers=headers, json=payload, timeout=self.timeout)\n response.raise_for_status()\n\n json = response.json()\n data = Data(result=json[\"data\"], metadata=json[\"metadata\"])\n\n except httpx.HTTPStatusError as e:\n response = e.response\n if response.status_code in {401, 403}:\n self.status = \"Please, provide a valid API Key. You can create one at https://dev.agentql.com.\"\n else:\n try:\n error_json = response.json()\n logger.error(\n f\"Failure response: '{response.status_code} {response.reason_phrase}' with body: {error_json}\"\n )\n msg = error_json[\"error_info\"] if \"error_info\" in error_json else error_json[\"detail\"]\n except (ValueError, TypeError):\n msg = f\"HTTP {e}.\"\n self.status = msg\n raise ValueError(self.status) from e\n\n else:\n self.status = data\n return data\n" + "value": "import httpx\nfrom loguru import logger\n\nfrom langflow.custom import Component\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langflow.io import (\n BoolInput,\n DropdownInput,\n IntInput,\n MessageTextInput,\n MultilineInput,\n Output,\n SecretStrInput,\n)\nfrom langflow.schema import Data\n\n\nclass AgentQL(Component):\n display_name = \"Extract Web Data\"\n description = \"Extracts structured data from a web page using an AgentQL query or a Natural Language description.\"\n documentation: str = \"https://docs.agentql.com/rest-api/api-reference\"\n icon = \"AgentQL\"\n name = \"AgentQL\"\n\n inputs = [\n SecretStrInput(\n name=\"api_key\",\n display_name=\"API Key\",\n required=True,\n password=True,\n info=\"Your AgentQL API key from dev.agentql.com\",\n ),\n MessageTextInput(\n name=\"url\",\n display_name=\"URL\",\n required=True,\n info=\"The URL of the public web page you want to extract data from.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"query\",\n display_name=\"AgentQL Query\",\n required=False,\n info=\"The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.\",\n tool_mode=True,\n ),\n MultilineInput(\n name=\"prompt\",\n display_name=\"Prompt\",\n required=False,\n info=\"A Natural Language description of the data to extract from the page. Alternative to AgentQL query.\",\n tool_mode=True,\n ),\n BoolInput(\n name=\"is_stealth_mode_enabled\",\n display_name=\"Enable Stealth Mode (Beta)\",\n info=\"Enable experimental anti-bot evasion strategies. May not work for all websites at all times.\",\n value=False,\n advanced=True,\n ),\n IntInput(\n name=\"timeout\",\n display_name=\"Timeout\",\n info=\"Seconds to wait for a request.\",\n value=900,\n advanced=True,\n ),\n DropdownInput(\n name=\"mode\",\n display_name=\"Request Mode\",\n info=\"'standard' uses deep data analysis, while 'fast' trades some depth of analysis for speed.\",\n options=[\"fast\", \"standard\"],\n value=\"fast\",\n advanced=True,\n ),\n IntInput(\n name=\"wait_for\",\n display_name=\"Wait For\",\n info=\"Seconds to wait for the page to load before extracting data.\",\n value=0,\n range_spec=RangeSpec(min=0, max=10, step_type=\"int\"),\n advanced=True,\n ),\n BoolInput(\n name=\"is_scroll_to_bottom_enabled\",\n display_name=\"Enable scroll to bottom\",\n info=\"Scroll to bottom of the page before extracting data.\",\n value=False,\n advanced=True,\n ),\n BoolInput(\n name=\"is_screenshot_enabled\",\n display_name=\"Enable screenshot\",\n info=\"Take a screenshot before extracting data. Returned in 'metadata' as a Base64 string.\",\n value=False,\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"data\", method=\"build_output\"),\n ]\n\n def build_output(self) -> Data:\n endpoint = \"https://api.agentql.com/v1/query-data\"\n headers = {\n \"X-API-Key\": self.api_key,\n \"Content-Type\": \"application/json\",\n \"X-TF-Request-Origin\": \"langflow\",\n }\n\n payload = {\n \"url\": self.url,\n \"query\": self.query,\n \"prompt\": self.prompt,\n \"params\": {\n \"mode\": self.mode,\n \"wait_for\": self.wait_for,\n \"is_scroll_to_bottom_enabled\": self.is_scroll_to_bottom_enabled,\n \"is_screenshot_enabled\": self.is_screenshot_enabled,\n },\n \"metadata\": {\n \"experimental_stealth_mode_enabled\": self.is_stealth_mode_enabled,\n },\n }\n\n if not self.prompt and not self.query:\n self.status = \"Either Query or Prompt must be provided.\"\n raise ValueError(self.status)\n if self.prompt and self.query:\n self.status = \"Both Query and Prompt can't be provided at the same time.\"\n raise ValueError(self.status)\n\n try:\n response = httpx.post(endpoint, headers=headers, json=payload, timeout=self.timeout)\n response.raise_for_status()\n\n json = response.json()\n data = Data(result=json[\"data\"], metadata=json[\"metadata\"])\n\n except httpx.HTTPStatusError as e:\n response = e.response\n if response.status_code == httpx.codes.UNAUTHORIZED:\n self.status = \"Please, provide a valid API Key. You can create one at https://dev.agentql.com.\"\n else:\n try:\n error_json = response.json()\n logger.error(\n f\"Failure response: '{response.status_code} {response.reason_phrase}' with body: {error_json}\"\n )\n msg = error_json[\"error_info\"] if \"error_info\" in error_json else error_json[\"detail\"]\n except (ValueError, TypeError):\n msg = f\"HTTP {e}.\"\n self.status = msg\n raise ValueError(self.status) from e\n\n else:\n self.status = data\n return data\n" }, - "params": { - "_input_type": "DictInput", + "is_screenshot_enabled": { + "_input_type": "BoolInput", "advanced": true, - "display_name": "Additional Params", + "display_name": "Enable screenshot", "dynamic": false, - "info": "The additional params to send with the request. For details refer to https://docs.agentql.com/rest-api/api-reference#request-body.", - "list": true, + "info": "Take a screenshot before extracting data. Returned in 'metadata' as a Base64 string.", + "list": false, "list_add_label": "Add More", - "name": "params", + "name": "is_screenshot_enabled", "placeholder": "", "required": false, "show": true, "title_case": false, "tool_mode": false, - "trace_as_input": true, - "type": "dict", - "value": { - "is_screenshot_enabled": false, - "is_scroll_to_bottom_enabled": false, - "mode": "fast", - "wait_for": 0 - } + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "is_scroll_to_bottom_enabled": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Enable scroll to bottom", + "dynamic": false, + "info": "Scroll to bottom of the page before extracting data.", + "list": false, + "list_add_label": "Add More", + "name": "is_scroll_to_bottom_enabled", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "is_stealth_mode_enabled": { + "_input_type": "BoolInput", + "advanced": true, + "display_name": "Enable Stealth Mode (Beta)", + "dynamic": false, + "info": "Enable experimental anti-bot evasion strategies. May not work for all websites at all times.", + "list": false, + "list_add_label": "Add More", + "name": "is_stealth_mode_enabled", + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "bool", + "value": false + }, + "mode": { + "_input_type": "DropdownInput", + "advanced": true, + "combobox": false, + "dialog_inputs": {}, + "display_name": "Request Mode", + "dynamic": false, + "info": "'standard' uses deep data analysis, while 'fast' trades some depth of analysis for speed.", + "name": "mode", + "options": [ + "fast", + "standard" + ], + "options_metadata": [], + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "str", + "value": "fast" }, "prompt": { "_input_type": "MultilineInput", "advanced": false, + "copy_field": false, "display_name": "Prompt", "dynamic": false, "info": "A Natural Language description of the data to extract from the page. Alternative to AgentQL query.", @@ -1188,6 +1247,7 @@ "query": { "_input_type": "MultilineInput", "advanced": false, + "copy_field": false, "display_name": "AgentQL Query", "dynamic": false, "info": "The AgentQL query to execute. Learn more at https://docs.agentql.com/agentql-query or use a prompt.", @@ -1214,7 +1274,7 @@ "advanced": true, "display_name": "Timeout", "dynamic": false, - "info": "Timeout in seconds for the request. Increase if data extraction takes too long.", + "info": "Seconds to wait for a request.", "list": false, "list_add_label": "Add More", "name": "timeout", @@ -1299,6 +1359,19 @@ "name": "tags", "sortable": false, "type": "str" + }, + { + "default": true, + "description": "Indicates whether the tool is currently active. Set to True to activate this tool.", + "disable_edit": false, + "display_name": "Enable", + "edit_mode": "popover", + "filterable": true, + "formatter": "boolean", + "hidden": false, + "name": "status", + "sortable": true, + "type": "boolean" } ] }, @@ -1312,6 +1385,7 @@ { "description": "build_output(api_key: Message, url: Message) - Extracts structured data from a web page using an AgentQL query or a Natural Language description.", "name": "AgentQL-build_output", + "status": true, "tags": [ "AgentQL-build_output" ] @@ -1340,6 +1414,30 @@ "trace_as_metadata": true, "type": "str", "value": "" + }, + "wait_for": { + "_input_type": "IntInput", + "advanced": true, + "display_name": "Wait For", + "dynamic": false, + "info": "Seconds to wait for the page to load before extracting data.", + "list": false, + "list_add_label": "Add More", + "name": "wait_for", + "placeholder": "", + "range_spec": { + "max": 10, + "min": 0, + "step": 0.1, + "step_type": "int" + }, + "required": false, + "show": true, + "title_case": false, + "tool_mode": false, + "trace_as_metadata": true, + "type": "int", + "value": 0 } }, "tool_mode": true @@ -1348,7 +1446,7 @@ "type": "AgentQL" }, "dragging": false, - "id": "AgentQL-R0YLG", + "id": "AgentQL-7RVLY", "measured": { "height": 599, "width": 320 @@ -1362,7 +1460,7 @@ }, { "data": { - "id": "Agent-7PMCu", + "id": "Agent-O0yDh", "node": { "base_classes": [ "Message" @@ -2038,7 +2136,7 @@ "type": "Agent" }, "dragging": false, - "id": "Agent-7PMCu", + "id": "Agent-O0yDh", "measured": { "height": 621, "width": 320 @@ -2052,7 +2150,7 @@ }, { "data": { - "id": "note-1ajq3", + "id": "note-XsoMT", "node": { "description": "### 💡 Add your OpenAI API key here", "display_name": "", @@ -2064,7 +2162,7 @@ "type": "note" }, "dragging": false, - "id": "note-1ajq3", + "id": "note-XsoMT", "measured": { "height": 324, "width": 324 @@ -2078,7 +2176,7 @@ }, { "data": { - "id": "note-9nOJ2", + "id": "note-WnGqC", "node": { "description": "### 💡 Add your AgentQL API key here", "display_name": "", @@ -2091,7 +2189,7 @@ }, "dragging": false, "height": 346, - "id": "note-9nOJ2", + "id": "note-WnGqC", "measured": { "height": 346, "width": 324 @@ -2105,7 +2203,7 @@ }, { "data": { - "id": "note-JxjIs", + "id": "note-Qqusp", "node": { "description": "# Price Deal Finder \n\nThis flow extracts structured data from a URL.\n## Prerequisites\n\n* **[AgentQL API Key](https://dev.agentql.com/api-keys)**\n* **[OpenAI API Key](https://platform.openai.com/)**\n* **[TavilyAI Search API Key](https://tavily.com/)**\n\n## Quick Start\n\n1. Add your [AgentQL API Key](https://dev.agentql.com/api-keys) to the **AgentQL** component.\n2. Add your [OpenAI API Key](https://platform.openai.com/) to the **Agent** component.\n3. Add your [TavilyAI Search API Key](https://tavily.com/) to the **Tavily AI Search** component.\n4. Click **Playground** and enter a product in chat. For example, search \"Nintendo Switch - OLed Model - w/ White Joy-Con\")\n* The **Agent** component populates the **Tavily AI Search** component's **Search Query** field, and the **Agent QL** component's **URL** and **Query** fields. \n\n* The **Agent** returns a structured response to your searcn in the chat.", "display_name": "", @@ -2116,7 +2214,7 @@ }, "dragging": false, "height": 674, - "id": "note-JxjIs", + "id": "note-Qqusp", "measured": { "height": 674, "width": 467 @@ -2132,7 +2230,7 @@ }, { "data": { - "id": "note-VxmZ9", + "id": "note-jNCi3", "node": { "description": "### 💡 Add your Tavily AI Search key here", "display_name": "", @@ -2145,7 +2243,7 @@ }, "dragging": false, "height": 324, - "id": "note-VxmZ9", + "id": "note-jNCi3", "measured": { "height": 324, "width": 344 @@ -2161,18 +2259,17 @@ } ], "viewport": { - "x": 546.0173634466885, - "y": 279.0139837091223, - "zoom": 0.671291450402032 + "x": 407.36179700368467, + "y": 437.56262661430094, + "zoom": 0.7174828925593176 } }, "description": "Searches and compares product prices across multiple e-commerce platforms. ", "endpoint_name": null, - "id": "675468b8-08ab-44b0-aef1-87d76a75570a", + "id": "b91c6971-fe73-479b-b5d3-d08ac651ea21", "is_component": false, "last_tested_version": "1.2.0", "name": "Price Deal Finder", - "icon": "DollarSign", "tags": [ "web-scraping", "agents"