diff --git a/404.html b/404.html index d6dc080b25..a4f6c10879 100644 --- a/404.html +++ b/404.html @@ -10,7 +10,7 @@ - +
diff --git a/Components/components-memories.html b/Components/components-memories.html index 8c534ac292..4ee2ab3eaa 100644 --- a/Components/components-memories.html +++ b/Components/components-memories.html @@ -10,7 +10,7 @@ - + diff --git a/Components/components-tools.html b/Components/components-tools.html index 6a79aec74f..c9b191685e 100644 --- a/Components/components-tools.html +++ b/Components/components-tools.html @@ -10,7 +10,7 @@ - + diff --git a/Configuration/configuration-custom-database.html b/Configuration/configuration-custom-database.html index 557c923f08..a787ba0395 100644 --- a/Configuration/configuration-custom-database.html +++ b/Configuration/configuration-custom-database.html @@ -10,7 +10,7 @@ - + diff --git a/agents-overview.html b/agents-overview.html index 10eaf8cf19..6eae4d084a 100644 --- a/agents-overview.html +++ b/agents-overview.html @@ -10,7 +10,7 @@ - + diff --git a/agents-tool-calling-agent-component.html b/agents-tool-calling-agent-component.html index 4ff4286507..308c4ef72a 100644 --- a/agents-tool-calling-agent-component.html +++ b/agents-tool-calling-agent-component.html @@ -10,7 +10,7 @@ - + diff --git a/api.html b/api.html index 7739092f7d..3bfb947972 100644 --- a/api.html +++ b/api.html @@ -10,7 +10,7 @@ - + diff --git a/api/add-user.html b/api/add-user.html index 77b6801ab4..235d2a0ebe 100644 --- a/api/add-user.html +++ b/api/add-user.html @@ -10,7 +10,7 @@ - + diff --git a/api/auto-login.html b/api/auto-login.html index 678e6c66ba..eb983345bb 100644 --- a/api/auto-login.html +++ b/api/auto-login.html @@ -10,7 +10,7 @@ - + diff --git a/api/build-flow.html b/api/build-flow.html index db8ce88dbc..977959b6e2 100644 --- a/api/build-flow.html +++ b/api/build-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/build-vertex-stream.html b/api/build-vertex-stream.html index ee7171969b..a52cd55143 100644 --- a/api/build-vertex-stream.html +++ b/api/build-vertex-stream.html @@ -10,7 +10,7 @@ - + diff --git a/api/build-vertex.html b/api/build-vertex.html index 961af1cba7..f86ff809dc 100644 --- a/api/build-vertex.html +++ b/api/build-vertex.html @@ -10,7 +10,7 @@ - + diff --git a/api/check-if-store-has-api-key.html b/api/check-if-store-has-api-key.html index b2f4774500..83022acfbd 100644 --- a/api/check-if-store-has-api-key.html +++ b/api/check-if-store-has-api-key.html @@ -10,7 +10,7 @@ - + diff --git a/api/check-if-store-is-enabled.html b/api/check-if-store-is-enabled.html index 0a3e84b90b..ba0c813ee6 100644 --- a/api/check-if-store-is-enabled.html +++ b/api/check-if-store-is-enabled.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-api-key-route.html b/api/create-api-key-route.html index 138f67bd4f..ac5e2bd31f 100644 --- a/api/create-api-key-route.html +++ b/api/create-api-key-route.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-flow.html b/api/create-flow.html index 50fc78dd0a..e1bd02fa59 100644 --- a/api/create-flow.html +++ b/api/create-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-flows.html b/api/create-flows.html index 3e64973c5c..06a8e6f46f 100644 --- a/api/create-flows.html +++ b/api/create-flows.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-folder.html b/api/create-folder.html index 8552b5927b..3643ee1206 100644 --- a/api/create-folder.html +++ b/api/create-folder.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-upload-file.html b/api/create-upload-file.html index e8d9e40419..1467997612 100644 --- a/api/create-upload-file.html +++ b/api/create-upload-file.html @@ -10,7 +10,7 @@ - + diff --git a/api/create-variable.html b/api/create-variable.html index 03db553c8d..e2ce550881 100644 --- a/api/create-variable.html +++ b/api/create-variable.html @@ -10,7 +10,7 @@ - + diff --git a/api/custom-component-update.html b/api/custom-component-update.html index 00ad8ad3af..9ecc0a74f2 100644 --- a/api/custom-component-update.html +++ b/api/custom-component-update.html @@ -10,7 +10,7 @@ - + diff --git a/api/custom-component.html b/api/custom-component.html index 9f82202ead..7af5b33534 100644 --- a/api/custom-component.html +++ b/api/custom-component.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-api-key-route.html b/api/delete-api-key-route.html index 94564b85f3..5515f601c8 100644 --- a/api/delete-api-key-route.html +++ b/api/delete-api-key-route.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-file.html b/api/delete-file.html index c70a5cf9ff..888300bc5d 100644 --- a/api/delete-file.html +++ b/api/delete-file.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-flow.html b/api/delete-flow.html index 9e0dd0d399..745a10613b 100644 --- a/api/delete-flow.html +++ b/api/delete-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-folder.html b/api/delete-folder.html index 6a4ed436c2..77ceb1bd8a 100644 --- a/api/delete-folder.html +++ b/api/delete-folder.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-messages-session.html b/api/delete-messages-session.html index 6d6aff0aec..648cd26605 100644 --- a/api/delete-messages-session.html +++ b/api/delete-messages-session.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-messages.html b/api/delete-messages.html index dca8e0b9b9..1da874d013 100644 --- a/api/delete-messages.html +++ b/api/delete-messages.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-multiple-flows.html b/api/delete-multiple-flows.html index e8a0bc8457..c84a38359c 100644 --- a/api/delete-multiple-flows.html +++ b/api/delete-multiple-flows.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-user.html b/api/delete-user.html index 44c670ebf8..3719bcc00c 100644 --- a/api/delete-user.html +++ b/api/delete-user.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-variable.html b/api/delete-variable.html index ae5f2eb195..e0fb20cf2d 100644 --- a/api/delete-variable.html +++ b/api/delete-variable.html @@ -10,7 +10,7 @@ - + diff --git a/api/delete-vertex-builds.html b/api/delete-vertex-builds.html index 754a8b6681..48eefd2cbf 100644 --- a/api/delete-vertex-builds.html +++ b/api/delete-vertex-builds.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-component.html b/api/download-component.html index 3d160d6405..e6e12f554d 100644 --- a/api/download-component.html +++ b/api/download-component.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-file-1.html b/api/download-file-1.html index 6ee7ef43de..b8bd0e8cb7 100644 --- a/api/download-file-1.html +++ b/api/download-file-1.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-file.html b/api/download-file.html index 98adfdfa66..5d846b2d9d 100644 --- a/api/download-file.html +++ b/api/download-file.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-image.html b/api/download-image.html index 2f6a1fb3f5..1d05942c24 100644 --- a/api/download-image.html +++ b/api/download-image.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-multiple-file.html b/api/download-multiple-file.html index a8ce50db50..d2530fd6d9 100644 --- a/api/download-multiple-file.html +++ b/api/download-multiple-file.html @@ -10,7 +10,7 @@ - + diff --git a/api/download-profile-picture.html b/api/download-profile-picture.html index a5d3563271..b8e90c98b1 100644 --- a/api/download-profile-picture.html +++ b/api/download-profile-picture.html @@ -10,7 +10,7 @@ - + diff --git a/api/experimental-run-flow.html b/api/experimental-run-flow.html index 14273bee69..77c44ee80b 100644 --- a/api/experimental-run-flow.html +++ b/api/experimental-run-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-all.html b/api/get-all.html index 13c55a96a1..e2b27696cf 100644 --- a/api/get-all.html +++ b/api/get-all.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-api-keys-route.html b/api/get-api-keys-route.html index e98bac4eaa..30ddde89b2 100644 --- a/api/get-api-keys-route.html +++ b/api/get-api-keys-route.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-components.html b/api/get-components.html index df7a4eac89..1ac19992a7 100644 --- a/api/get-components.html +++ b/api/get-components.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-config.html b/api/get-config.html index 1161f82833..1b7415753c 100644 --- a/api/get-config.html +++ b/api/get-config.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-list-of-components-liked-by-user.html b/api/get-list-of-components-liked-by-user.html index 2c2fa83d9c..56100feb55 100644 --- a/api/get-list-of-components-liked-by-user.html +++ b/api/get-list-of-components-liked-by-user.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-messages.html b/api/get-messages.html index 531dce4e6e..f4c5501e5c 100644 --- a/api/get-messages.html +++ b/api/get-messages.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-starter-projects.html b/api/get-starter-projects.html index 698090903a..534a15ecdb 100644 --- a/api/get-starter-projects.html +++ b/api/get-starter-projects.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-tags.html b/api/get-tags.html index 3794a6a319..828d6461e0 100644 --- a/api/get-tags.html +++ b/api/get-tags.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-task-status.html b/api/get-task-status.html index f56893b2be..2a9e09d25b 100644 --- a/api/get-task-status.html +++ b/api/get-task-status.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-transactions.html b/api/get-transactions.html index 89810c88cd..9fc37095e4 100644 --- a/api/get-transactions.html +++ b/api/get-transactions.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-version.html b/api/get-version.html index 3c9ec87d79..09335c0921 100644 --- a/api/get-version.html +++ b/api/get-version.html @@ -10,7 +10,7 @@ - + diff --git a/api/get-vertex-builds.html b/api/get-vertex-builds.html index 2ce3316cae..0e0caf4991 100644 --- a/api/get-vertex-builds.html +++ b/api/get-vertex-builds.html @@ -10,7 +10,7 @@ - + diff --git a/api/health-check.html b/api/health-check.html index fa5c14df09..2568f64283 100644 --- a/api/health-check.html +++ b/api/health-check.html @@ -10,7 +10,7 @@ - + diff --git a/api/health.html b/api/health.html index 5735635541..b12f0e09a5 100644 --- a/api/health.html +++ b/api/health.html @@ -10,7 +10,7 @@ - + diff --git a/api/like-component.html b/api/like-component.html index 8138c2be11..419a128e5d 100644 --- a/api/like-component.html +++ b/api/like-component.html @@ -10,7 +10,7 @@ - + diff --git a/api/list-files.html b/api/list-files.html index 9b5c2107a3..69a0810d67 100644 --- a/api/list-files.html +++ b/api/list-files.html @@ -10,7 +10,7 @@ - + diff --git a/api/list-profile-pictures.html b/api/list-profile-pictures.html index 2f31139dc5..499a263b35 100644 --- a/api/list-profile-pictures.html +++ b/api/list-profile-pictures.html @@ -10,7 +10,7 @@ - + diff --git a/api/login-to-get-access-token.html b/api/login-to-get-access-token.html index a60de49537..327182d89d 100644 --- a/api/login-to-get-access-token.html +++ b/api/login-to-get-access-token.html @@ -10,7 +10,7 @@ - + diff --git a/api/logout.html b/api/logout.html index 34a4643517..8613814b4e 100644 --- a/api/logout.html +++ b/api/logout.html @@ -10,7 +10,7 @@ - + diff --git a/api/logs.html b/api/logs.html index d179c1c4f3..e0082e766e 100644 --- a/api/logs.html +++ b/api/logs.html @@ -10,7 +10,7 @@ - + diff --git a/api/patch-user.html b/api/patch-user.html index 804c1da0cf..19713dd7df 100644 --- a/api/patch-user.html +++ b/api/patch-user.html @@ -10,7 +10,7 @@ - + diff --git a/api/post-validate-code.html b/api/post-validate-code.html index b468ddc5f5..a2aa4ea238 100644 --- a/api/post-validate-code.html +++ b/api/post-validate-code.html @@ -10,7 +10,7 @@ - + diff --git a/api/post-validate-prompt.html b/api/post-validate-prompt.html index fcb276fed9..dbd1ff1531 100644 --- a/api/post-validate-prompt.html +++ b/api/post-validate-prompt.html @@ -10,7 +10,7 @@ - + diff --git a/api/process-1.html b/api/process-1.html index fe4fbcdfff..6224e58bfa 100644 --- a/api/process-1.html +++ b/api/process-1.html @@ -10,7 +10,7 @@ - + diff --git a/api/process.html b/api/process.html index aafb687cd6..0fcde7b93c 100644 --- a/api/process.html +++ b/api/process.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-all-users.html b/api/read-all-users.html index a9c9df02b6..83eafa29ea 100644 --- a/api/read-all-users.html +++ b/api/read-all-users.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-basic-examples.html b/api/read-basic-examples.html index 24978f3256..6ae7229e18 100644 --- a/api/read-basic-examples.html +++ b/api/read-basic-examples.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-current-user.html b/api/read-current-user.html index a18dc25633..dfa2f76f56 100644 --- a/api/read-current-user.html +++ b/api/read-current-user.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-flow.html b/api/read-flow.html index a2dd4281fc..a96e649d21 100644 --- a/api/read-flow.html +++ b/api/read-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-flows.html b/api/read-flows.html index 1e92e98459..11791b9653 100644 --- a/api/read-flows.html +++ b/api/read-flows.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-folder.html b/api/read-folder.html index 50291ef81b..fde5b9ecf7 100644 --- a/api/read-folder.html +++ b/api/read-folder.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-folders.html b/api/read-folders.html index 86004d4e38..e832d2ed84 100644 --- a/api/read-folders.html +++ b/api/read-folders.html @@ -10,7 +10,7 @@ - + diff --git a/api/read-variables.html b/api/read-variables.html index 90a35ad3c1..cfdc034a2f 100644 --- a/api/read-variables.html +++ b/api/read-variables.html @@ -10,7 +10,7 @@ - + diff --git a/api/refresh-token.html b/api/refresh-token.html index 0d03e780d8..319e41a97d 100644 --- a/api/refresh-token.html +++ b/api/refresh-token.html @@ -10,7 +10,7 @@ - + diff --git a/api/reset-password.html b/api/reset-password.html index 945c10382a..82ae1e407a 100644 --- a/api/reset-password.html +++ b/api/reset-password.html @@ -10,7 +10,7 @@ - + diff --git a/api/retrieve-vertices-order.html b/api/retrieve-vertices-order.html index fc1eb6cf59..07e2bde3fb 100644 --- a/api/retrieve-vertices-order.html +++ b/api/retrieve-vertices-order.html @@ -10,7 +10,7 @@ - + diff --git a/api/save-store-api-key.html b/api/save-store-api-key.html index 9c48d5f9f2..01e5ab5a47 100644 --- a/api/save-store-api-key.html +++ b/api/save-store-api-key.html @@ -10,7 +10,7 @@ - + diff --git a/api/share-component.html b/api/share-component.html index 80a24f12ab..a1feaacc28 100644 --- a/api/share-component.html +++ b/api/share-component.html @@ -10,7 +10,7 @@ - + diff --git a/api/simplified-run-flow.html b/api/simplified-run-flow.html index 334ff926cd..f27b3d4843 100644 --- a/api/simplified-run-flow.html +++ b/api/simplified-run-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/stream-logs.html b/api/stream-logs.html index e025d7b3e8..75f0bbe3f4 100644 --- a/api/stream-logs.html +++ b/api/stream-logs.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-flow.html b/api/update-flow.html index f435131083..cae4a88f1c 100644 --- a/api/update-flow.html +++ b/api/update-flow.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-folder.html b/api/update-folder.html index ce08080c38..a5159fa40d 100644 --- a/api/update-folder.html +++ b/api/update-folder.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-message.html b/api/update-message.html index eee71ee284..41e3810261 100644 --- a/api/update-message.html +++ b/api/update-message.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-session-id.html b/api/update-session-id.html index d8f832dd34..aeb8827d79 100644 --- a/api/update-session-id.html +++ b/api/update-session-id.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-shared-component.html b/api/update-shared-component.html index 508b5887f7..456b8725c9 100644 --- a/api/update-shared-component.html +++ b/api/update-shared-component.html @@ -10,7 +10,7 @@ - + diff --git a/api/update-variable.html b/api/update-variable.html index 1cf0de72ef..e754746b30 100644 --- a/api/update-variable.html +++ b/api/update-variable.html @@ -10,7 +10,7 @@ - + diff --git a/api/upload-file-1.html b/api/upload-file-1.html index 3856f355df..2d0008e125 100644 --- a/api/upload-file-1.html +++ b/api/upload-file-1.html @@ -10,7 +10,7 @@ - + diff --git a/api/upload-file-2.html b/api/upload-file-2.html index 0e2ba1bf65..a826ba6701 100644 --- a/api/upload-file-2.html +++ b/api/upload-file-2.html @@ -10,7 +10,7 @@ - + diff --git a/api/upload-file.html b/api/upload-file.html index 8f58fefd84..b52bef6a85 100644 --- a/api/upload-file.html +++ b/api/upload-file.html @@ -10,7 +10,7 @@ - + diff --git a/api/webhook-run-flow.html b/api/webhook-run-flow.html index ff1dcb9f79..b0441a73cc 100644 --- a/api/webhook-run-flow.html +++ b/api/webhook-run-flow.html @@ -10,7 +10,7 @@ - + diff --git a/assets/files/Conversational_Notion_Agent-5aa96d840d4d38fe4b064400d06ac109.json b/assets/files/Conversational_Notion_Agent-5aa96d840d4d38fe4b064400d06ac109.json deleted file mode 100644 index 2b8b4063d8..0000000000 --- a/assets/files/Conversational_Notion_Agent-5aa96d840d4d38fe4b064400d06ac109.json +++ /dev/null @@ -1 +0,0 @@ -{"id":"e070f0be-edc4-4512-bb0f-e53307062a26","data":{"nodes":[{"id":"AddContentToPage-ZezUn","type":"genericNode","position":{"x":1416.217259177943,"y":1709.6205867919527},"data":{"type":"AddContentToPage","node":{"template":{"_type":"Component","block_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"block_id","value":"","display_name":"Page/Block ID","advanced":true,"dynamic":false,"info":"The ID of the page/block to add the content.","title_case":false,"type":"str","_input_type":"StrInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\nfrom typing import Dict, Any, Union\nfrom markdown import markdown\nfrom bs4 import BeautifulSoup\nimport requests\nfrom langflow.io import Output\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput, MultilineInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\nfrom pydantic import BaseModel, Field\n\n\nclass AddContentToPage(LCToolComponent):\n display_name: str = \"Add Content to Page \"\n description: str = \"Convert markdown text to Notion blocks and append them to a Notion page.\"\n documentation: str = \"https://developers.notion.com/reference/patch-block-children\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n MultilineInput(\n name=\"markdown_text\",\n display_name=\"Markdown Text\",\n info=\"The markdown text to convert to Notion blocks.\",\n ),\n StrInput(\n name=\"block_id\",\n display_name=\"Page/Block ID\",\n info=\"The ID of the page/block to add the content.\",\n ),\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class AddContentToPageSchema(BaseModel):\n markdown_text: str = Field(..., description=\"The markdown text to convert to Notion blocks.\")\n block_id: str = Field(..., description=\"The ID of the page/block to add the content.\")\n\n def run_model(self) -> Data:\n result = self._add_content_to_page(self.markdown_text, self.block_id)\n return Data(data=result, text=json.dumps(result))\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"add_content_to_notion_page\",\n description=\"Convert markdown text to Notion blocks and append them to a Notion page.\",\n func=self._add_content_to_page,\n args_schema=self.AddContentToPageSchema,\n )\n\n def _add_content_to_page(self, markdown_text: str, block_id: str) -> Union[Dict[str, Any], str]:\n try:\n html_text = markdown(markdown_text)\n soup = BeautifulSoup(html_text, \"html.parser\")\n blocks = self.process_node(soup)\n\n url = f\"https://api.notion.com/v1/blocks/{block_id}/children\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Content-Type\": \"application/json\",\n \"Notion-Version\": \"2022-06-28\",\n }\n\n data = {\n \"children\": blocks,\n }\n\n response = requests.patch(url, headers=headers, json=data)\n response.raise_for_status()\n\n return response.json()\n except requests.exceptions.RequestException as e:\n error_message = f\"Error: Failed to add content to Notion page. {str(e)}\"\n if hasattr(e, \"response\") and e.response is not None:\n error_message += f\" Status code: {e.response.status_code}, Response: {e.response.text}\"\n return error_message\n except Exception as e:\n return f\"Error: An unexpected error occurred while adding content to Notion page. {str(e)}\"\n\n def process_node(self, node):\n blocks = []\n if isinstance(node, str):\n text = node.strip()\n if text:\n if text.startswith(\"#\"):\n heading_level = text.count(\"#\", 0, 6)\n heading_text = text[heading_level:].strip()\n if heading_level == 1:\n blocks.append(self.create_block(\"heading_1\", heading_text))\n elif heading_level == 2:\n blocks.append(self.create_block(\"heading_2\", heading_text))\n elif heading_level == 3:\n blocks.append(self.create_block(\"heading_3\", heading_text))\n else:\n blocks.append(self.create_block(\"paragraph\", text))\n elif node.name == \"h1\":\n blocks.append(self.create_block(\"heading_1\", node.get_text(strip=True)))\n elif node.name == \"h2\":\n blocks.append(self.create_block(\"heading_2\", node.get_text(strip=True)))\n elif node.name == \"h3\":\n blocks.append(self.create_block(\"heading_3\", node.get_text(strip=True)))\n elif node.name == \"p\":\n code_node = node.find(\"code\")\n if code_node:\n code_text = code_node.get_text()\n language, code = self.extract_language_and_code(code_text)\n blocks.append(self.create_block(\"code\", code, language=language))\n elif self.is_table(str(node)):\n blocks.extend(self.process_table(node))\n else:\n blocks.append(self.create_block(\"paragraph\", node.get_text(strip=True)))\n elif node.name == \"ul\":\n blocks.extend(self.process_list(node, \"bulleted_list_item\"))\n elif node.name == \"ol\":\n blocks.extend(self.process_list(node, \"numbered_list_item\"))\n elif node.name == \"blockquote\":\n blocks.append(self.create_block(\"quote\", node.get_text(strip=True)))\n elif node.name == \"hr\":\n blocks.append(self.create_block(\"divider\", \"\"))\n elif node.name == \"img\":\n blocks.append(self.create_block(\"image\", \"\", image_url=node.get(\"src\")))\n elif node.name == \"a\":\n blocks.append(self.create_block(\"bookmark\", node.get_text(strip=True), link_url=node.get(\"href\")))\n elif node.name == \"table\":\n blocks.extend(self.process_table(node))\n\n for child in node.children:\n if isinstance(child, str):\n continue\n blocks.extend(self.process_node(child))\n\n return blocks\n\n def extract_language_and_code(self, code_text):\n lines = code_text.split(\"\\n\")\n language = lines[0].strip()\n code = \"\\n\".join(lines[1:]).strip()\n return language, code\n\n def is_code_block(self, text):\n return text.startswith(\"```\")\n\n def extract_code_block(self, text):\n lines = text.split(\"\\n\")\n language = lines[0].strip(\"`\").strip()\n code = \"\\n\".join(lines[1:]).strip(\"`\").strip()\n return language, code\n\n def is_table(self, text):\n rows = text.split(\"\\n\")\n if len(rows) < 2:\n return False\n\n has_separator = False\n for i, row in enumerate(rows):\n if \"|\" in row:\n cells = [cell.strip() for cell in row.split(\"|\")]\n cells = [cell for cell in cells if cell] # Remove empty cells\n if i == 1 and all(set(cell) <= set(\"-|\") for cell in cells):\n has_separator = True\n elif not cells:\n return False\n\n return has_separator and len(rows) >= 3\n\n def process_list(self, node, list_type):\n blocks = []\n for item in node.find_all(\"li\"):\n item_text = item.get_text(strip=True)\n checked = item_text.startswith(\"[x]\")\n is_checklist = item_text.startswith(\"[ ]\") or checked\n\n if is_checklist:\n item_text = item_text.replace(\"[x]\", \"\").replace(\"[ ]\", \"\").strip()\n blocks.append(self.create_block(\"to_do\", item_text, checked=checked))\n else:\n blocks.append(self.create_block(list_type, item_text))\n return blocks\n\n def process_table(self, node):\n blocks = []\n header_row = node.find(\"thead\").find(\"tr\") if node.find(\"thead\") else None\n body_rows = node.find(\"tbody\").find_all(\"tr\") if node.find(\"tbody\") else []\n\n if header_row or body_rows:\n table_width = max(\n len(header_row.find_all([\"th\", \"td\"])) if header_row else 0,\n max(len(row.find_all([\"th\", \"td\"])) for row in body_rows),\n )\n\n table_block = self.create_block(\"table\", \"\", table_width=table_width, has_column_header=bool(header_row))\n blocks.append(table_block)\n\n if header_row:\n header_cells = [cell.get_text(strip=True) for cell in header_row.find_all([\"th\", \"td\"])]\n header_row_block = self.create_block(\"table_row\", header_cells)\n blocks.append(header_row_block)\n\n for row in body_rows:\n cells = [cell.get_text(strip=True) for cell in row.find_all([\"th\", \"td\"])]\n row_block = self.create_block(\"table_row\", cells)\n blocks.append(row_block)\n\n return blocks\n\n def create_block(self, block_type: str, content: str, **kwargs) -> Dict[str, Any]:\n block: dict[str, Any] = {\n \"object\": \"block\",\n \"type\": block_type,\n block_type: {},\n }\n\n if block_type in [\n \"paragraph\",\n \"heading_1\",\n \"heading_2\",\n \"heading_3\",\n \"bulleted_list_item\",\n \"numbered_list_item\",\n \"quote\",\n ]:\n block[block_type][\"rich_text\"] = [\n {\n \"type\": \"text\",\n \"text\": {\n \"content\": content,\n },\n }\n ]\n elif block_type == \"to_do\":\n block[block_type][\"rich_text\"] = [\n {\n \"type\": \"text\",\n \"text\": {\n \"content\": content,\n },\n }\n ]\n block[block_type][\"checked\"] = kwargs.get(\"checked\", False)\n elif block_type == \"code\":\n block[block_type][\"rich_text\"] = [\n {\n \"type\": \"text\",\n \"text\": {\n \"content\": content,\n },\n }\n ]\n block[block_type][\"language\"] = kwargs.get(\"language\", \"plain text\")\n elif block_type == \"image\":\n block[block_type] = {\"type\": \"external\", \"external\": {\"url\": kwargs.get(\"image_url\", \"\")}}\n elif block_type == \"divider\":\n pass\n elif block_type == \"bookmark\":\n block[block_type][\"url\"] = kwargs.get(\"link_url\", \"\")\n elif block_type == \"table\":\n block[block_type][\"table_width\"] = kwargs.get(\"table_width\", 0)\n block[block_type][\"has_column_header\"] = kwargs.get(\"has_column_header\", False)\n block[block_type][\"has_row_header\"] = kwargs.get(\"has_row_header\", False)\n elif block_type == \"table_row\":\n block[block_type][\"cells\"] = [[{\"type\": \"text\", \"text\": {\"content\": cell}} for cell in content]]\n\n return block\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"markdown_text":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"markdown_text","value":"","display_name":"Markdown Text","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The markdown text to convert to Notion blocks.","title_case":false,"type":"str","_input_type":"MultilineInput"},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"}},"description":"Convert markdown text to Notion blocks and append them to a Notion page.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"Add Content to Page ","documentation":"https://developers.notion.com/reference/patch-block-children","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["markdown_text","block_id","notion_secret"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"AddContentToPage-ZezUn","description":"Convert markdown text to Notion blocks and append them to a Notion page.","display_name":"Add Content to Page "},"selected":false,"width":384,"height":330,"dragging":false,"positionAbsolute":{"x":1416.217259177943,"y":1709.6205867919527}},{"id":"NotionPageCreator-6SCB5","type":"genericNode","position":{"x":1413.9782390799146,"y":2051.645785494985},"data":{"type":"NotionPageCreator","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\nfrom typing import Dict, Any, Union\nimport requests\nfrom pydantic import BaseModel, Field\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput, MultilineInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\nfrom langflow.io import Output\n\nclass NotionPageCreator(LCToolComponent):\n display_name: str = \"Create Page \"\n description: str = \"A component for creating Notion pages.\"\n documentation: str = \"https://docs.langflow.org/integrations/notion/page-create\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n StrInput(\n name=\"database_id\",\n display_name=\"Database ID\",\n info=\"The ID of the Notion database.\",\n ),\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n MultilineInput(\n name=\"properties_json\",\n display_name=\"Properties (JSON)\",\n info=\"The properties of the new page as a JSON string.\",\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionPageCreatorSchema(BaseModel):\n database_id: str = Field(..., description=\"The ID of the Notion database.\")\n properties_json: str = Field(..., description=\"The properties of the new page as a JSON string.\")\n\n def run_model(self) -> Data:\n result = self._create_notion_page(self.database_id, self.properties_json)\n if isinstance(result, str):\n # An error occurred, return it as text\n return Data(text=result)\n else:\n # Success, return the created page data\n output = \"Created page properties:\\n\"\n for prop_name, prop_value in result.get(\"properties\", {}).items():\n output += f\"{prop_name}: {prop_value}\\n\"\n return Data(text=output, data=result)\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"create_notion_page\",\n description=\"Create a new page in a Notion database. IMPORTANT: Use the tool to check the Database properties for more details before using this tool.\",\n func=self._create_notion_page,\n args_schema=self.NotionPageCreatorSchema,\n )\n\n def _create_notion_page(self, database_id: str, properties_json: str) -> Union[Dict[str, Any], str]:\n if not database_id or not properties_json:\n return \"Invalid input. Please provide 'database_id' and 'properties_json'.\"\n\n try:\n properties = json.loads(properties_json)\n except json.JSONDecodeError as e:\n return f\"Invalid properties format. Please provide a valid JSON string. Error: {str(e)}\"\n\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Content-Type\": \"application/json\",\n \"Notion-Version\": \"2022-06-28\",\n }\n\n data = {\n \"parent\": {\"database_id\": database_id},\n \"properties\": properties,\n }\n\n try:\n response = requests.post(\"https://api.notion.com/v1/pages\", headers=headers, json=data)\n response.raise_for_status()\n result = response.json()\n return result\n except requests.exceptions.RequestException as e:\n error_message = f\"Failed to create Notion page. Error: {str(e)}\"\n if hasattr(e, \"response\") and e.response is not None:\n error_message += f\" Status code: {e.response.status_code}, Response: {e.response.text}\"\n return error_message\n\n def __call__(self, *args, **kwargs):\n return self._create_notion_page(*args, **kwargs)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"database_id","value":"","display_name":"Database ID","advanced":true,"dynamic":false,"info":"The ID of the Notion database.","title_case":false,"type":"str","_input_type":"StrInput"},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"properties_json":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"properties_json","value":"","display_name":"Properties (JSON)","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The properties of the new page as a JSON string.","title_case":false,"type":"str","_input_type":"MultilineInput"}},"description":"A component for creating Notion pages.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"Create Page ","documentation":"https://docs.langflow.org/integrations/notion/page-create","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["database_id","notion_secret","properties_json"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionPageCreator-6SCB5","description":"A component for creating Notion pages.","display_name":"Create Page "},"selected":false,"width":384,"height":302,"dragging":false,"positionAbsolute":{"x":1413.9782390799146,"y":2051.645785494985}},{"id":"NotionDatabaseProperties-aeWil","type":"genericNode","position":{"x":1004.5753613670959,"y":1713.914531491452},"data":{"type":"NotionDatabaseProperties","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\nfrom typing import Dict, Union\nfrom pydantic import BaseModel, Field\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\nfrom langflow.io import Output\n\nclass NotionDatabaseProperties(LCToolComponent):\n display_name: str = \"List Database Properties \"\n description: str = \"Retrieve properties of a Notion database.\"\n documentation: str = \"https://docs.langflow.org/integrations/notion/list-database-properties\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n StrInput(\n name=\"database_id\",\n display_name=\"Database ID\",\n info=\"The ID of the Notion database.\",\n ),\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionDatabasePropertiesSchema(BaseModel):\n database_id: str = Field(..., description=\"The ID of the Notion database.\")\n\n def run_model(self) -> Data:\n result = self._fetch_database_properties(self.database_id)\n if isinstance(result, str):\n # An error occurred, return it as text\n return Data(text=result)\n else:\n # Success, return the properties\n return Data(text=str(result), data=result)\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"notion_database_properties\",\n description=\"Retrieve properties of a Notion database. Input should include the database ID.\",\n func=self._fetch_database_properties,\n args_schema=self.NotionDatabasePropertiesSchema,\n )\n\n def _fetch_database_properties(self, database_id: str) -> Union[Dict, str]:\n url = f\"https://api.notion.com/v1/databases/{database_id}\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Notion-Version\": \"2022-06-28\", # Use the latest supported version\n }\n try:\n response = requests.get(url, headers=headers)\n response.raise_for_status()\n data = response.json()\n properties = data.get(\"properties\", {})\n return properties\n except requests.exceptions.RequestException as e:\n return f\"Error fetching Notion database properties: {str(e)}\"\n except ValueError as e:\n return f\"Error parsing Notion API response: {str(e)}\"\n except Exception as e:\n return f\"An unexpected error occurred: {str(e)}\"\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"database_id","value":"","display_name":"Database ID","advanced":true,"dynamic":false,"info":"The ID of the Notion database.","title_case":false,"type":"str","_input_type":"StrInput"},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"}},"description":"Retrieve properties of a Notion database.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"List Database Properties ","documentation":"https://docs.langflow.org/integrations/notion/list-database-properties","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["database_id","notion_secret"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionDatabaseProperties-aeWil","description":"Retrieve properties of a Notion database.","display_name":"List Database Properties "},"selected":false,"width":384,"height":302,"dragging":false,"positionAbsolute":{"x":1004.5753613670959,"y":1713.914531491452}},{"id":"NotionListPages-znA3w","type":"genericNode","position":{"x":1006.1848442547046,"y":2022.7880909242833},"data":{"type":"NotionListPages","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\nimport json\nfrom typing import Dict, Any, List, Optional\nfrom pydantic import BaseModel, Field\nfrom langflow.io import Output\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput, MultilineInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\n\n\nclass NotionListPages(LCToolComponent):\n display_name: str = \"List Pages \"\n description: str = (\n \"Query a Notion database with filtering and sorting. \"\n \"The input should be a JSON string containing the 'filter' and 'sorts' objects. \"\n \"Example input:\\n\"\n '{\"filter\": {\"property\": \"Status\", \"select\": {\"equals\": \"Done\"}}, \"sorts\": [{\"timestamp\": \"created_time\", \"direction\": \"descending\"}]}'\n )\n documentation: str = \"https://docs.langflow.org/integrations/notion/list-pages\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n StrInput(\n name=\"database_id\",\n display_name=\"Database ID\",\n info=\"The ID of the Notion database to query.\",\n ),\n MultilineInput(\n name=\"query_json\",\n display_name=\"Database query (JSON)\",\n info=\"A JSON string containing the filters and sorts that will be used for querying the database. Leave empty for no filters or sorts.\",\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n class NotionListPagesSchema(BaseModel):\n database_id: str = Field(..., description=\"The ID of the Notion database to query.\")\n query_json: Optional[str] = Field(\n default=\"\",\n description=\"A JSON string containing the filters and sorts for querying the database. Leave empty for no filters or sorts.\",\n )\n\n def run_model(self) -> List[Data]:\n result = self._query_notion_database(self.database_id, self.query_json)\n\n if isinstance(result, str):\n # An error occurred, return it as a single record\n return [Data(text=result)]\n\n records = []\n combined_text = f\"Pages found: {len(result)}\\n\\n\"\n\n for page in result:\n page_data = {\n \"id\": page[\"id\"],\n \"url\": page[\"url\"],\n \"created_time\": page[\"created_time\"],\n \"last_edited_time\": page[\"last_edited_time\"],\n \"properties\": page[\"properties\"],\n }\n\n text = (\n f\"id: {page['id']}\\n\"\n f\"url: {page['url']}\\n\"\n f\"created_time: {page['created_time']}\\n\"\n f\"last_edited_time: {page['last_edited_time']}\\n\"\n f\"properties: {json.dumps(page['properties'], indent=2)}\\n\\n\"\n )\n\n combined_text += text\n records.append(Data(text=text, **page_data))\n\n self.status = records\n return records\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"notion_list_pages\",\n description=self.description,\n func=self._query_notion_database,\n args_schema=self.NotionListPagesSchema,\n )\n\n def _query_notion_database(self, database_id: str, query_json: Optional[str] = None) -> List[Dict[str, Any]] | str:\n url = f\"https://api.notion.com/v1/databases/{database_id}/query\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Content-Type\": \"application/json\",\n \"Notion-Version\": \"2022-06-28\",\n }\n\n query_payload = {}\n if query_json and query_json.strip():\n try:\n query_payload = json.loads(query_json)\n except json.JSONDecodeError as e:\n return f\"Invalid JSON format for query: {str(e)}\"\n\n try:\n response = requests.post(url, headers=headers, json=query_payload)\n response.raise_for_status()\n results = response.json()\n return results[\"results\"]\n except requests.exceptions.RequestException as e:\n return f\"Error querying Notion database: {str(e)}\"\n except KeyError:\n return \"Unexpected response format from Notion API\"\n except Exception as e:\n return f\"An unexpected error occurred: {str(e)}\"\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"database_id","value":"","display_name":"Database ID","advanced":true,"dynamic":false,"info":"The ID of the Notion database to query.","title_case":false,"type":"str","_input_type":"StrInput"},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"query_json":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"query_json","value":"","display_name":"Database query (JSON)","advanced":true,"input_types":["Message"],"dynamic":false,"info":"A JSON string containing the filters and sorts that will be used for querying the database. Leave empty for no filters or sorts.","title_case":false,"type":"str","_input_type":"MultilineInput"}},"description":"Query a Notion database with filtering and sorting. The input should be a JSON string containing the 'filter' and 'sorts' objects. Example input:\n{\"filter\": {\"property\": \"Status\", \"select\": {\"equals\": \"Done\"}}, \"sorts\": [{\"timestamp\": \"created_time\", \"direction\": \"descending\"}]}","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"List Pages ","documentation":"https://docs.langflow.org/integrations/notion/list-pages","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["notion_secret","database_id","query_json"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionListPages-znA3w","description":"Query a Notion database with filtering and sorting. The input should be a JSON string containing the 'filter' and 'sorts' objects. Example input:\n{\"filter\": {\"property\": \"Status\", \"select\": {\"equals\": \"Done\"}}, \"sorts\": [{\"timestamp\": \"created_time\", \"direction\": \"descending\"}]}","display_name":"List Pages "},"selected":false,"width":384,"height":470,"dragging":false,"positionAbsolute":{"x":1006.1848442547046,"y":2022.7880909242833}},{"id":"NotionUserList-C3eGn","type":"genericNode","position":{"x":2260.15497405973,"y":1717.4551881467207},"data":{"type":"NotionUserList","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\nfrom typing import List, Dict\nfrom pydantic import BaseModel\nfrom langflow.io import Output\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\n\n\nclass NotionUserList(LCToolComponent):\n display_name = \"List Users \"\n description = \"Retrieve users from Notion.\"\n documentation = \"https://docs.langflow.org/integrations/notion/list-users\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionUserListSchema(BaseModel):\n pass\n\n def run_model(self) -> List[Data]:\n users = self._list_users()\n records = []\n combined_text = \"\"\n\n for user in users:\n output = \"User:\\n\"\n for key, value in user.items():\n output += f\"{key.replace('_', ' ').title()}: {value}\\n\"\n output += \"________________________\\n\"\n\n combined_text += output\n records.append(Data(text=output, data=user))\n\n self.status = records\n return records\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"notion_list_users\",\n description=\"Retrieve users from Notion.\",\n func=self._list_users,\n args_schema=self.NotionUserListSchema,\n )\n\n def _list_users(self) -> List[Dict]:\n url = \"https://api.notion.com/v1/users\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Notion-Version\": \"2022-06-28\",\n }\n\n response = requests.get(url, headers=headers)\n response.raise_for_status()\n\n data = response.json()\n results = data[\"results\"]\n\n users = []\n for user in results:\n user_data = {\n \"id\": user[\"id\"],\n \"type\": user[\"type\"],\n \"name\": user.get(\"name\", \"\"),\n \"avatar_url\": user.get(\"avatar_url\", \"\"),\n }\n users.append(user_data)\n\n return users\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"}},"description":"Retrieve users from Notion.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"List Users ","documentation":"https://docs.langflow.org/integrations/notion/list-users","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["notion_secret"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionUserList-C3eGn","description":"Retrieve users from Notion.","display_name":"List Users "},"selected":true,"width":384,"height":302,"dragging":false,"positionAbsolute":{"x":2260.15497405973,"y":1717.4551881467207}},{"id":"NotionPageContent-SlL21","type":"genericNode","position":{"x":1826.4242329724448,"y":1715.6365113286927},"data":{"type":"NotionPageContent","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\nfrom pydantic import BaseModel, Field\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\nfrom langflow.io import Output\n\nclass NotionPageContent(LCToolComponent):\n display_name = \"Page Content Viewer \"\n description = \"Retrieve the content of a Notion page as plain text.\"\n documentation = \"https://docs.langflow.org/integrations/notion/page-content-viewer\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n StrInput(\n name=\"page_id\",\n display_name=\"Page ID\",\n info=\"The ID of the Notion page to retrieve.\",\n ),\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionPageContentSchema(BaseModel):\n page_id: str = Field(..., description=\"The ID of the Notion page to retrieve.\")\n\n def run_model(self) -> Data:\n result = self._retrieve_page_content(self.page_id)\n if isinstance(result, str) and result.startswith(\"Error:\"):\n # An error occurred, return it as text\n return Data(text=result)\n else:\n # Success, return the content\n return Data(text=result, data={\"content\": result})\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"notion_page_content\",\n description=\"Retrieve the content of a Notion page as plain text.\",\n func=self._retrieve_page_content,\n args_schema=self.NotionPageContentSchema,\n )\n\n def _retrieve_page_content(self, page_id: str) -> str:\n blocks_url = f\"https://api.notion.com/v1/blocks/{page_id}/children?page_size=100\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Notion-Version\": \"2022-06-28\",\n }\n try:\n blocks_response = requests.get(blocks_url, headers=headers)\n blocks_response.raise_for_status()\n blocks_data = blocks_response.json()\n return self.parse_blocks(blocks_data.get(\"results\", []))\n except requests.exceptions.RequestException as e:\n error_message = f\"Error: Failed to retrieve Notion page content. {str(e)}\"\n if hasattr(e, \"response\") and e.response is not None:\n error_message += f\" Status code: {e.response.status_code}, Response: {e.response.text}\"\n return error_message\n except Exception as e:\n return f\"Error: An unexpected error occurred while retrieving Notion page content. {str(e)}\"\n\n def parse_blocks(self, blocks: list) -> str:\n content = \"\"\n for block in blocks:\n block_type = block.get(\"type\")\n if block_type in [\"paragraph\", \"heading_1\", \"heading_2\", \"heading_3\", \"quote\"]:\n content += self.parse_rich_text(block[block_type].get(\"rich_text\", [])) + \"\\n\\n\"\n elif block_type in [\"bulleted_list_item\", \"numbered_list_item\"]:\n content += self.parse_rich_text(block[block_type].get(\"rich_text\", [])) + \"\\n\"\n elif block_type == \"to_do\":\n content += self.parse_rich_text(block[\"to_do\"].get(\"rich_text\", [])) + \"\\n\"\n elif block_type == \"code\":\n content += self.parse_rich_text(block[\"code\"].get(\"rich_text\", [])) + \"\\n\\n\"\n elif block_type == \"image\":\n content += f\"[Image: {block['image'].get('external', {}).get('url', 'No URL')}]\\n\\n\"\n elif block_type == \"divider\":\n content += \"---\\n\\n\"\n return content.strip()\n\n def parse_rich_text(self, rich_text: list) -> str:\n return \"\".join(segment.get(\"plain_text\", \"\") for segment in rich_text)\n\n def __call__(self, *args, **kwargs):\n return self._retrieve_page_content(*args, **kwargs)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"page_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"page_id","value":"","display_name":"Page ID","advanced":true,"dynamic":false,"info":"The ID of the Notion page to retrieve.","title_case":false,"type":"str","_input_type":"StrInput"}},"description":"Retrieve the content of a Notion page as plain text.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"Page Content Viewer ","documentation":"https://docs.langflow.org/integrations/notion/page-content-viewer","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["page_id","notion_secret"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionPageContent-SlL21","description":"Retrieve the content of a Notion page as plain text.","display_name":"Page Content Viewer "},"selected":false,"width":384,"height":330,"dragging":false,"positionAbsolute":{"x":1826.4242329724448,"y":1715.6365113286927}},{"id":"NotionSearch-VS2mI","type":"genericNode","position":{"x":2258.1166047519732,"y":2034.3959294952945},"data":{"type":"NotionSearch","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\nfrom typing import Dict, Any, List\nfrom pydantic import BaseModel, Field\nfrom langflow.io import Output\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput, DropdownInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\n\n\nclass NotionSearch(LCToolComponent):\n display_name: str = \"Search \"\n description: str = \"Searches all pages and databases that have been shared with an integration. The search field can be an empty value to show all values from that search\"\n documentation: str = \"https://docs.langflow.org/integrations/notion/search\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n StrInput(\n name=\"query\",\n display_name=\"Search Query\",\n info=\"The text that the API compares page and database titles against.\",\n ),\n DropdownInput(\n name=\"filter_value\",\n display_name=\"Filter Type\",\n info=\"Limits the results to either only pages or only databases.\",\n options=[\"page\", \"database\"],\n value=\"page\",\n ),\n DropdownInput(\n name=\"sort_direction\",\n display_name=\"Sort Direction\",\n info=\"The direction to sort the results.\",\n options=[\"ascending\", \"descending\"],\n value=\"descending\",\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionSearchSchema(BaseModel):\n query: str = Field(..., description=\"The search query text.\")\n filter_value: str = Field(default=\"page\", description=\"Filter type: 'page' or 'database'.\")\n sort_direction: str = Field(default=\"descending\", description=\"Sort direction: 'ascending' or 'descending'.\")\n\n def run_model(self) -> List[Data]:\n results = self._search_notion(self.query, self.filter_value, self.sort_direction)\n records = []\n combined_text = f\"Results found: {len(results)}\\n\\n\"\n\n for result in results:\n result_data = {\n \"id\": result[\"id\"],\n \"type\": result[\"object\"],\n \"last_edited_time\": result[\"last_edited_time\"],\n }\n\n if result[\"object\"] == \"page\":\n result_data[\"title_or_url\"] = result[\"url\"]\n text = f\"id: {result['id']}\\ntitle_or_url: {result['url']}\\n\"\n elif result[\"object\"] == \"database\":\n if \"title\" in result and isinstance(result[\"title\"], list) and len(result[\"title\"]) > 0:\n result_data[\"title_or_url\"] = result[\"title\"][0][\"plain_text\"]\n text = f\"id: {result['id']}\\ntitle_or_url: {result['title'][0]['plain_text']}\\n\"\n else:\n result_data[\"title_or_url\"] = \"N/A\"\n text = f\"id: {result['id']}\\ntitle_or_url: N/A\\n\"\n\n text += f\"type: {result['object']}\\nlast_edited_time: {result['last_edited_time']}\\n\\n\"\n combined_text += text\n records.append(Data(text=text, data=result_data))\n\n self.status = records\n return records\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"notion_search\",\n description=\"Search Notion pages and databases. Input should include the search query and optionally filter type and sort direction.\",\n func=self._search_notion,\n args_schema=self.NotionSearchSchema,\n )\n\n def _search_notion(\n self, query: str, filter_value: str = \"page\", sort_direction: str = \"descending\"\n ) -> List[Dict[str, Any]]:\n url = \"https://api.notion.com/v1/search\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Content-Type\": \"application/json\",\n \"Notion-Version\": \"2022-06-28\",\n }\n\n data = {\n \"query\": query,\n \"filter\": {\"value\": filter_value, \"property\": \"object\"},\n \"sort\": {\"direction\": sort_direction, \"timestamp\": \"last_edited_time\"},\n }\n\n response = requests.post(url, headers=headers, json=data)\n response.raise_for_status()\n\n results = response.json()\n return results[\"results\"]\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"filter_value":{"trace_as_metadata":true,"options":["page","database"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"filter_value","value":"page","display_name":"Filter Type","advanced":true,"dynamic":false,"info":"Limits the results to either only pages or only databases.","title_case":false,"type":"str","_input_type":"DropdownInput"},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"query":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"query","value":"","display_name":"Search Query","advanced":true,"dynamic":false,"info":"The text that the API compares page and database titles against.","title_case":false,"type":"str","_input_type":"StrInput"},"sort_direction":{"trace_as_metadata":true,"options":["ascending","descending"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"sort_direction","value":"descending","display_name":"Sort Direction","advanced":true,"dynamic":false,"info":"The direction to sort the results.","title_case":false,"type":"str","_input_type":"DropdownInput"}},"description":"Searches all pages and databases that have been shared with an integration. The search field can be an empty value to show all values from that search","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"Search ","documentation":"https://docs.langflow.org/integrations/notion/search","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["notion_secret","query","filter_value","sort_direction"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionSearch-VS2mI","description":"Searches all pages and databases that have been shared with an integration.","display_name":"Search "},"selected":false,"width":384,"height":386,"dragging":false,"positionAbsolute":{"x":2258.1166047519732,"y":2034.3959294952945}},{"id":"NotionPageUpdate-6FyYd","type":"genericNode","position":{"x":1827.0574354713603,"y":2055.9948126656136},"data":{"type":"NotionPageUpdate","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\nimport requests\nfrom typing import Dict, Any, Union\nfrom pydantic import BaseModel, Field\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.inputs import SecretStrInput, StrInput, MultilineInput\nfrom langflow.schema import Data\nfrom langflow.field_typing import Tool\nfrom langchain.tools import StructuredTool\nfrom loguru import logger\nfrom langflow.io import Output\n\nclass NotionPageUpdate(LCToolComponent):\n display_name: str = \"Update Page Property \"\n description: str = \"Update the properties of a Notion page.\"\n documentation: str = \"https://docs.langflow.org/integrations/notion/page-update\"\n icon = \"NotionDirectoryLoader\"\n\n inputs = [\n StrInput(\n name=\"page_id\",\n display_name=\"Page ID\",\n info=\"The ID of the Notion page to update.\",\n ),\n MultilineInput(\n name=\"properties\",\n display_name=\"Properties\",\n info=\"The properties to update on the page (as a JSON string or a dictionary).\",\n ),\n SecretStrInput(\n name=\"notion_secret\",\n display_name=\"Notion Secret\",\n info=\"The Notion integration token.\",\n required=True,\n ),\n ]\n outputs = [\n Output(name=\"example_output\", display_name=\"Data\", method=\"run_model\"),\n Output(name=\"example_tool_output\", display_name=\"Tool\", method=\"build_tool\"),\n ]\n\n class NotionPageUpdateSchema(BaseModel):\n page_id: str = Field(..., description=\"The ID of the Notion page to update.\")\n properties: Union[str, Dict[str, Any]] = Field(\n ..., description=\"The properties to update on the page (as a JSON string or a dictionary).\"\n )\n\n def run_model(self) -> Data:\n result = self._update_notion_page(self.page_id, self.properties)\n if isinstance(result, str):\n # An error occurred, return it as text\n return Data(text=result)\n else:\n # Success, return the updated page data\n output = \"Updated page properties:\\n\"\n for prop_name, prop_value in result.get(\"properties\", {}).items():\n output += f\"{prop_name}: {prop_value}\\n\"\n return Data(text=output, data=result)\n\n def build_tool(self) -> Tool:\n return StructuredTool.from_function(\n name=\"update_notion_page\",\n description=\"Update the properties of a Notion page. IMPORTANT: Use the tool to check the Database properties for more details before using this tool.\",\n func=self._update_notion_page,\n args_schema=self.NotionPageUpdateSchema,\n )\n\n def _update_notion_page(self, page_id: str, properties: Union[str, Dict[str, Any]]) -> Union[Dict[str, Any], str]:\n url = f\"https://api.notion.com/v1/pages/{page_id}\"\n headers = {\n \"Authorization\": f\"Bearer {self.notion_secret}\",\n \"Content-Type\": \"application/json\",\n \"Notion-Version\": \"2022-06-28\", # Use the latest supported version\n }\n\n # Parse properties if it's a string\n if isinstance(properties, str):\n try:\n parsed_properties = json.loads(properties)\n except json.JSONDecodeError as e:\n error_message = f\"Invalid JSON format for properties: {str(e)}\"\n logger.error(error_message)\n return error_message\n\n else:\n parsed_properties = properties\n\n data = {\"properties\": parsed_properties}\n\n try:\n logger.info(f\"Sending request to Notion API: URL: {url}, Data: {json.dumps(data)}\")\n response = requests.patch(url, headers=headers, json=data)\n response.raise_for_status()\n updated_page = response.json()\n\n logger.info(f\"Successfully updated Notion page. Response: {json.dumps(updated_page)}\")\n return updated_page\n except requests.exceptions.HTTPError as e:\n error_message = f\"HTTP Error occurred: {str(e)}\"\n if e.response is not None:\n error_message += f\"\\nStatus code: {e.response.status_code}\"\n error_message += f\"\\nResponse body: {e.response.text}\"\n logger.error(error_message)\n return error_message\n except requests.exceptions.RequestException as e:\n error_message = f\"An error occurred while making the request: {str(e)}\"\n logger.error(error_message)\n return error_message\n except Exception as e:\n error_message = f\"An unexpected error occurred: {str(e)}\"\n logger.error(error_message)\n return error_message\n\n def __call__(self, *args, **kwargs):\n return self._update_notion_page(*args, **kwargs)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"load_from_db":true,"required":true,"placeholder":"","show":true,"name":"notion_secret","value":"","display_name":"Notion Secret","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The Notion integration token.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"page_id":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"page_id","value":"","display_name":"Page ID","advanced":true,"dynamic":false,"info":"The ID of the Notion page to update.","title_case":false,"type":"str","_input_type":"StrInput"},"properties":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"properties","value":"","display_name":"Properties","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The properties to update on the page (as a JSON string or a dictionary).","title_case":false,"type":"str","_input_type":"MultilineInput"}},"description":"Update the properties of a Notion page.","icon":"NotionDirectoryLoader","base_classes":["Data","Tool"],"display_name":"Update Page Property ","documentation":"https://docs.langflow.org/integrations/notion/page-update","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"example_output","display_name":"Data","method":"run_model","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Tool"],"selected":"Tool","name":"example_tool_output","display_name":"Tool","method":"build_tool","value":"__UNDEFINED__","cache":true}],"field_order":["page_id","properties","notion_secret"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"NotionPageUpdate-6FyYd","description":"Update the properties of a Notion page.","display_name":"Update Page Property "},"selected":false,"width":384,"height":302,"dragging":false,"positionAbsolute":{"x":1827.0574354713603,"y":2055.9948126656136}},{"id":"ToolCallingAgent-50Gcd","type":"genericNode","position":{"x":2186.0530739759893,"y":612.1744804997304},"data":{"type":"ToolCallingAgent","node":{"template":{"_type":"Component","chat_history":{"trace_as_metadata":true,"list":true,"trace_as_input":true,"required":false,"placeholder":"","show":true,"name":"chat_history","value":"","display_name":"Chat History","advanced":false,"input_types":["Data"],"dynamic":false,"info":"","title_case":false,"type":"other","_input_type":"DataInput"},"llm":{"trace_as_metadata":true,"list":false,"required":true,"placeholder":"","show":true,"name":"llm","value":"","display_name":"Language Model","advanced":false,"input_types":["LanguageModel"],"dynamic":false,"info":"","title_case":false,"type":"other","_input_type":"HandleInput"},"tools":{"trace_as_metadata":true,"list":true,"required":false,"placeholder":"","show":true,"name":"tools","value":"","display_name":"Tools","advanced":false,"input_types":["Tool","BaseTool"],"dynamic":false,"info":"","title_case":false,"type":"other","_input_type":"HandleInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from typing import Optional, List\n\nfrom langchain.agents import create_tool_calling_agent\nfrom langchain_core.prompts import ChatPromptTemplate, PromptTemplate, HumanMessagePromptTemplate\nfrom langflow.base.agents.agent import LCToolsAgentComponent\nfrom langflow.inputs import MultilineInput\nfrom langflow.inputs.inputs import HandleInput, DataInput\nfrom langflow.schema import Data\n\n\nclass ToolCallingAgentComponent(LCToolsAgentComponent):\n display_name: str = \"Tool Calling Agent\"\n description: str = \"Agent that uses tools\"\n icon = \"LangChain\"\n beta = True\n name = \"ToolCallingAgent\"\n\n inputs = LCToolsAgentComponent._base_inputs + [\n HandleInput(name=\"llm\", display_name=\"Language Model\", input_types=[\"LanguageModel\"], required=True),\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"System Prompt\",\n info=\"System prompt for the agent.\",\n value=\"You are a helpful assistant\",\n ),\n MultilineInput(\n name=\"user_prompt\", display_name=\"Prompt\", info=\"This prompt must contain 'input' key.\", value=\"{input}\"\n ),\n DataInput(name=\"chat_history\", display_name=\"Chat History\", is_list=True, advanced=True),\n ]\n\n def get_chat_history_data(self) -> Optional[List[Data]]:\n return self.chat_history\n\n def create_agent_runnable(self):\n if \"input\" not in self.user_prompt:\n raise ValueError(\"Prompt must contain 'input' key.\")\n messages = [\n (\"system\", self.system_prompt),\n (\"placeholder\", \"{chat_history}\"),\n HumanMessagePromptTemplate(prompt=PromptTemplate(input_variables=[\"input\"], template=self.user_prompt)),\n (\"placeholder\", \"{agent_scratchpad}\"),\n ]\n prompt = ChatPromptTemplate.from_messages(messages)\n return create_tool_calling_agent(self.llm, self.tools, prompt)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"handle_parsing_errors":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"handle_parsing_errors","value":true,"display_name":"Handle Parse Errors","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool","_input_type":"BoolInput"},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"input_value","value":"","display_name":"Input","advanced":false,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str","_input_type":"MessageTextInput"},"max_iterations":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"max_iterations","value":15,"display_name":"Max Iterations","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"int","_input_type":"IntInput"},"system_prompt":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"system_prompt","value":"","display_name":"System Prompt","advanced":false,"input_types":["Message"],"dynamic":false,"info":"System prompt for the agent.","title_case":false,"type":"str","_input_type":"MultilineInput"},"user_prompt":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"user_prompt","value":"{input}","display_name":"Prompt","advanced":true,"input_types":["Message"],"dynamic":false,"info":"This prompt must contain 'input' key.","title_case":false,"type":"str","_input_type":"MultilineInput"},"verbose":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"verbose","value":true,"display_name":"Verbose","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"bool","_input_type":"BoolInput"}},"description":"Agent that uses tools","icon":"LangChain","base_classes":["AgentExecutor","Message"],"display_name":"Tool Calling Agent","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["AgentExecutor"],"selected":"AgentExecutor","name":"agent","display_name":"Agent","method":"build_agent","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["Message"],"selected":"Message","name":"response","display_name":"Response","method":"message_response","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","handle_parsing_errors","verbose","max_iterations","tools","llm","system_prompt","user_prompt","chat_history"],"beta":true,"edited":false,"lf_version":"1.0.17"},"id":"ToolCallingAgent-50Gcd"},"selected":false,"width":384,"height":532,"dragging":false,"positionAbsolute":{"x":2186.0530739759893,"y":612.1744804997304}},{"id":"ChatOutput-TSCup","type":"genericNode","position":{"x":2649.190603849412,"y":841.0466487848925},"data":{"type":"ChatOutput","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, MessageTextInput, Output\nfrom langflow.memory import store_message\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_NAME_AI, MESSAGE_SENDER_USER\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n name = \"ChatOutput\"\n\n inputs = [\n MessageTextInput(\n name=\"input_value\",\n display_name=\"Text\",\n info=\"Message to be passed as output.\",\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_AI,\n advanced=True,\n info=\"Type of sender.\",\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_AI,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"data_template\",\n display_name=\"Data Template\",\n value=\"{text}\",\n advanced=True,\n info=\"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.\",\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n )\n if (\n self.session_id\n and isinstance(message, Message)\n and isinstance(message.text, str)\n and self.should_store_message\n ):\n store_message(\n message,\n flow_id=self.graph.flow_id,\n )\n self.message.value = message\n\n self.status = message\n return message\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"data_template":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"data_template","value":"{text}","display_name":"Data Template","advanced":true,"input_types":["Message"],"dynamic":false,"info":"Template to convert Data to Text. If left empty, it will be dynamically set to the Data's text key.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"input_value","value":"","display_name":"Text","advanced":false,"input_types":["Message"],"dynamic":false,"info":"Message to be passed as output.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"sender":{"trace_as_metadata":true,"options":["Machine","User"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"sender","value":"Machine","display_name":"Sender Type","advanced":true,"dynamic":false,"info":"Type of sender.","title_case":false,"type":"str","_input_type":"DropdownInput"},"sender_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"sender_name","value":"AI","display_name":"Sender Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"Name of the sender.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"session_id":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"session_id","value":"","display_name":"Session ID","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The session ID of the chat. If empty, the current session ID parameter will be used.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"should_store_message":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"should_store_message","value":true,"display_name":"Store Messages","advanced":true,"dynamic":false,"info":"Store the message in the history.","title_case":false,"type":"bool","_input_type":"BoolInput"}},"description":"Display a chat message in the Playground.","icon":"ChatOutput","base_classes":["Message"],"display_name":"Chat Output","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"message","display_name":"Message","method":"message_response","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","should_store_message","sender","sender_name","session_id","data_template"],"beta":false,"edited":false,"lf_version":"1.0.17"},"id":"ChatOutput-TSCup"},"selected":false,"width":384,"height":302,"positionAbsolute":{"x":2649.190603849412,"y":841.0466487848925},"dragging":false},{"id":"ChatInput-bcq6D","type":"genericNode","position":{"x":557.6262725075026,"y":724.8518930903978},"data":{"type":"ChatInput","node":{"template":{"_type":"Component","files":{"trace_as_metadata":true,"file_path":"","fileTypes":["txt","md","mdx","csv","json","yaml","yml","xml","html","htm","pdf","docx","py","sh","sql","js","ts","tsx","jpg","jpeg","png","bmp","image"],"list":true,"required":false,"placeholder":"","show":true,"name":"files","value":"","display_name":"Files","advanced":true,"dynamic":false,"info":"Files to be sent with the message.","title_case":false,"type":"file","_input_type":"FileInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langflow.base.data.utils import IMG_FILE_TYPES, TEXT_FILE_TYPES\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.inputs import BoolInput\nfrom langflow.io import DropdownInput, FileInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import store_message\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, MESSAGE_SENDER_NAME_USER\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n name = \"ChatInput\"\n\n inputs = [\n MultilineInput(\n name=\"input_value\",\n display_name=\"Text\",\n value=\"\",\n info=\"Message to be passed as input.\",\n ),\n BoolInput(\n name=\"should_store_message\",\n display_name=\"Store Messages\",\n info=\"Store the message in the history.\",\n value=True,\n advanced=True,\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER],\n value=MESSAGE_SENDER_USER,\n info=\"Type of sender.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Name of the sender.\",\n value=MESSAGE_SENDER_NAME_USER,\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n FileInput(\n name=\"files\",\n display_name=\"Files\",\n file_types=TEXT_FILE_TYPES + IMG_FILE_TYPES,\n info=\"Files to be sent with the message.\",\n advanced=True,\n is_list=True,\n ),\n ]\n outputs = [\n Output(display_name=\"Message\", name=\"message\", method=\"message_response\"),\n ]\n\n def message_response(self) -> Message:\n message = Message(\n text=self.input_value,\n sender=self.sender,\n sender_name=self.sender_name,\n session_id=self.session_id,\n files=self.files,\n )\n\n if (\n self.session_id\n and isinstance(message, Message)\n and isinstance(message.text, str)\n and self.should_store_message\n ):\n store_message(\n message,\n flow_id=self.graph.flow_id,\n )\n self.message.value = message\n\n self.status = message\n return message\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"input_value","value":"list users","display_name":"Text","advanced":false,"input_types":["Message"],"dynamic":false,"info":"Message to be passed as input.","title_case":false,"type":"str","_input_type":"MultilineInput"},"sender":{"trace_as_metadata":true,"options":["Machine","User"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"sender","value":"User","display_name":"Sender Type","advanced":true,"dynamic":false,"info":"Type of sender.","title_case":false,"type":"str","_input_type":"DropdownInput"},"sender_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"sender_name","value":"User","display_name":"Sender Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"Name of the sender.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"session_id":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"session_id","value":"","display_name":"Session ID","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The session ID of the chat. If empty, the current session ID parameter will be used.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"should_store_message":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"should_store_message","value":true,"display_name":"Store Messages","advanced":true,"dynamic":false,"info":"Store the message in the history.","title_case":false,"type":"bool","_input_type":"BoolInput"}},"description":"Get chat inputs from the Playground.","icon":"ChatInput","base_classes":["Message"],"display_name":"Chat Input","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"message","display_name":"Message","method":"message_response","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","should_store_message","sender","sender_name","session_id","files"],"beta":false,"edited":false,"lf_version":"1.0.17"},"id":"ChatInput-bcq6D"},"selected":false,"width":384,"height":302,"positionAbsolute":{"x":557.6262725075026,"y":724.8518930903978},"dragging":false},{"id":"ToolkitComponent-2lNG0","type":"genericNode","position":{"x":1731.8884789245508,"y":1378.7846304343796},"data":{"type":"ToolkitComponent","node":{"template":{"_type":"Component","tools":{"trace_as_metadata":true,"list":true,"required":false,"placeholder":"","show":true,"name":"tools","value":"","display_name":"Tools","advanced":false,"input_types":["Tool"],"dynamic":false,"info":"List of tools to combine.","title_case":false,"type":"other","_input_type":"HandleInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from typing import List\r\nfrom langflow.custom import Component\r\nfrom langflow.inputs import HandleInput, MessageTextInput\r\nfrom langflow.template import Output\r\nfrom langflow.field_typing import Tool, Embeddings\r\nfrom langchain.tools.base import BaseTool, StructuredTool\r\nfrom langflow.schema import Data\r\n\r\nclass ToolkitComponent(Component):\r\n display_name = \"Toolkit\"\r\n description = \"Combines multiple tools into a single list of tools.\"\r\n icon = \"pocket-knife\"\r\n\r\n inputs = [\r\n HandleInput(\r\n name=\"tools\",\r\n display_name=\"Tools\",\r\n input_types=[\"Tool\"],\r\n info=\"List of tools to combine.\",\r\n is_list=True,\r\n ),\r\n ]\r\n\r\n outputs = [\r\n Output(display_name=\"Tools\", name=\"generated_tools\", method=\"generate_toolkit\"),\r\n Output(display_name=\"Tool Data\", name=\"tool_data\", method=\"generate_tool_data\"),\r\n ]\r\n\r\n def generate_toolkit(self) -> List[BaseTool]:\r\n combined_tools = []\r\n name_count = {}\r\n for index, tool in enumerate(self.tools):\r\n self.log(f\"Processing tool {index}: {type(tool)}\")\r\n if isinstance(tool, (BaseTool, StructuredTool)):\r\n processed_tool = tool\r\n elif hasattr(tool, 'build_tool'):\r\n processed_tool = tool.build_tool()\r\n else:\r\n self.log(f\"Unsupported tool type: {type(tool)}. Attempting to process anyway.\")\r\n processed_tool = tool\r\n\r\n original_name = getattr(processed_tool, 'name', f\"UnnamedTool_{index}\")\r\n self.log(f\"Original tool name: {original_name}\")\r\n\r\n if original_name not in name_count:\r\n name_count[original_name] = 0\r\n final_name = original_name\r\n else:\r\n name_count[original_name] += 1\r\n final_name = f\"{original_name}_{name_count[original_name]}\"\r\n\r\n if hasattr(processed_tool, 'name'):\r\n processed_tool.name = final_name\r\n\r\n self.log(f\"Final tool name: {final_name}\")\r\n\r\n if isinstance(processed_tool, StructuredTool) and hasattr(processed_tool, 'args_schema'):\r\n processed_tool.args_schema.name = f\"{final_name}_Schema\"\r\n\r\n combined_tools.append(processed_tool)\r\n\r\n debug_info = \"\\n\".join([f\"Tool {i}: {getattr(tool, 'name', f'UnnamedTool_{i}')} (Original: {getattr(tool, '_original_name', 'N/A')}) - Type: {type(tool)}\" for i, tool in enumerate(combined_tools)])\r\n self.log(\"Final toolkit composition:\")\r\n self.log(debug_info)\r\n\r\n\r\n self.status = combined_tools\r\n return combined_tools\r\n\r\n def generate_tool_data(self) -> List[Data]:\r\n tool_data = []\r\n for tool in self.generate_toolkit():\r\n tool_data.append(Data(\r\n data={\r\n \"name\": getattr(tool, 'name', 'Unnamed Tool'),\r\n \"description\": getattr(tool, 'description', 'No description available')\r\n }\r\n ))\r\n return tool_data","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false}},"description":"Combines multiple tools into a single list of tools.","icon":"pocket-knife","base_classes":["BaseTool","Data"],"display_name":"Toolkit","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["BaseTool"],"selected":"BaseTool","name":"generated_tools","display_name":"Tools","method":"generate_toolkit","value":"__UNDEFINED__","cache":true},{"types":["Data"],"selected":"Data","name":"tool_data","display_name":"Tool Data","method":"generate_tool_data","value":"__UNDEFINED__","cache":true,"hidden":true}],"field_order":["tools"],"beta":false,"edited":true,"lf_version":"1.0.17"},"id":"ToolkitComponent-2lNG0"},"selected":false,"width":384,"height":292,"dragging":false,"positionAbsolute":{"x":1731.8884789245508,"y":1378.7846304343796}},{"id":"OpenAIModel-BJWIg","type":"genericNode","position":{"x":1718.9773974162958,"y":603.4642741725065},"data":{"type":"OpenAIModel","node":{"template":{"_type":"Component","api_key":{"load_from_db":true,"required":false,"placeholder":"","show":true,"name":"api_key","value":"","display_name":"OpenAI API Key","advanced":false,"input_types":["Message"],"dynamic":false,"info":"The OpenAI API Key to use for the OpenAI model.","title_case":false,"password":true,"type":"str","_input_type":"SecretStrInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import operator\nfrom functools import reduce\n\nfrom langflow.field_typing.range_spec import RangeSpec\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import OPENAI_MODEL_NAMES\nfrom langflow.field_typing import LanguageModel\nfrom langflow.inputs import (\n BoolInput,\n DictInput,\n DropdownInput,\n FloatInput,\n IntInput,\n SecretStrInput,\n StrInput,\n)\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n name = \"OpenAIModel\"\n\n inputs = LCModelComponent._base_inputs + [\n IntInput(\n name=\"max_tokens\",\n display_name=\"Max Tokens\",\n advanced=True,\n info=\"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n range_spec=RangeSpec(min=0, max=128000),\n ),\n DictInput(name=\"model_kwargs\", display_name=\"Model Kwargs\", advanced=True),\n BoolInput(\n name=\"json_mode\",\n display_name=\"JSON Mode\",\n advanced=True,\n info=\"If True, it will output JSON regardless of passing a schema.\",\n ),\n DictInput(\n name=\"output_schema\",\n is_list=True,\n display_name=\"Schema\",\n advanced=True,\n info=\"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.\",\n ),\n DropdownInput(\n name=\"model_name\",\n display_name=\"Model Name\",\n advanced=False,\n options=OPENAI_MODEL_NAMES,\n value=OPENAI_MODEL_NAMES[0],\n ),\n StrInput(\n name=\"openai_api_base\",\n display_name=\"OpenAI API Base\",\n advanced=True,\n info=\"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.\",\n ),\n SecretStrInput(\n name=\"api_key\",\n display_name=\"OpenAI API Key\",\n info=\"The OpenAI API Key to use for the OpenAI model.\",\n advanced=False,\n value=\"OPENAI_API_KEY\",\n ),\n FloatInput(name=\"temperature\", display_name=\"Temperature\", value=0.1),\n IntInput(\n name=\"seed\",\n display_name=\"Seed\",\n info=\"The seed controls the reproducibility of the job.\",\n advanced=True,\n value=1,\n ),\n ]\n\n def build_model(self) -> LanguageModel: # type: ignore[type-var]\n # self.output_schema is a list of dictionaries\n # let's convert it to a dictionary\n output_schema_dict: dict[str, str] = reduce(operator.ior, self.output_schema or {}, {})\n openai_api_key = self.api_key\n temperature = self.temperature\n model_name: str = self.model_name\n max_tokens = self.max_tokens\n model_kwargs = self.model_kwargs or {}\n openai_api_base = self.openai_api_base or \"https://api.openai.com/v1\"\n json_mode = bool(output_schema_dict) or self.json_mode\n seed = self.seed\n\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature if temperature is not None else 0.1,\n seed=seed,\n )\n if json_mode:\n if output_schema_dict:\n output = output.with_structured_output(schema=output_schema_dict, method=\"json_mode\") # type: ignore\n else:\n output = output.bind(response_format={\"type\": \"json_object\"}) # type: ignore\n\n return output # type: ignore\n\n def _get_exception_message(self, e: Exception):\n \"\"\"\n Get a message from an OpenAI exception.\n\n Args:\n exception (Exception): The exception to get the message from.\n\n Returns:\n str: The message from the exception.\n \"\"\"\n\n try:\n from openai import BadRequestError\n except ImportError:\n return\n if isinstance(e, BadRequestError):\n message = e.body.get(\"message\") # type: ignore\n if message:\n return message\n return\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"input_value":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"input_value","value":"","display_name":"Input","advanced":true,"input_types":["Message"],"dynamic":false,"info":"","title_case":false,"type":"str","_input_type":"MessageInput"},"json_mode":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"json_mode","value":false,"display_name":"JSON Mode","advanced":true,"dynamic":false,"info":"If True, it will output JSON regardless of passing a schema.","title_case":false,"type":"bool","_input_type":"BoolInput"},"max_tokens":{"trace_as_metadata":true,"range_spec":{"step_type":"float","min":0,"max":128000,"step":0.1},"list":false,"required":false,"placeholder":"","show":true,"name":"max_tokens","value":"","display_name":"Max Tokens","advanced":true,"dynamic":false,"info":"The maximum number of tokens to generate. Set to 0 for unlimited tokens.","title_case":false,"type":"int","_input_type":"IntInput"},"model_kwargs":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"name":"model_kwargs","value":{},"display_name":"Model Kwargs","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"dict","_input_type":"DictInput"},"model_name":{"trace_as_metadata":true,"options":["gpt-4o-mini","gpt-4o","gpt-4-turbo","gpt-4-turbo-preview","gpt-4","gpt-3.5-turbo","gpt-3.5-turbo-0125"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"model_name","value":"gpt-4o","display_name":"Model Name","advanced":false,"dynamic":false,"info":"","title_case":false,"type":"str","_input_type":"DropdownInput"},"openai_api_base":{"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"openai_api_base","value":"","display_name":"OpenAI API Base","advanced":true,"dynamic":false,"info":"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1. You can change this to use other APIs like JinaChat, LocalAI and Prem.","title_case":false,"type":"str","_input_type":"StrInput"},"output_schema":{"trace_as_input":true,"list":true,"required":false,"placeholder":"","show":true,"name":"output_schema","value":{},"display_name":"Schema","advanced":true,"dynamic":false,"info":"The schema for the Output of the model. You must pass the word JSON in the prompt. If left blank, JSON mode will be disabled.","title_case":false,"type":"dict","_input_type":"DictInput"},"seed":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"seed","value":1,"display_name":"Seed","advanced":true,"dynamic":false,"info":"The seed controls the reproducibility of the job.","title_case":false,"type":"int","_input_type":"IntInput"},"stream":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"stream","value":false,"display_name":"Stream","advanced":true,"dynamic":false,"info":"Stream the response from the model. Streaming works only in Chat.","title_case":false,"type":"bool","_input_type":"BoolInput"},"system_message":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"system_message","value":"","display_name":"System Message","advanced":true,"input_types":["Message"],"dynamic":false,"info":"System message to pass to the model.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"temperature":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"temperature","value":"0.2","display_name":"Temperature","advanced":true,"dynamic":false,"info":"","title_case":false,"type":"float","_input_type":"FloatInput"}},"description":"Generates text using OpenAI LLMs.","icon":"OpenAI","base_classes":["LanguageModel","Message"],"display_name":"OpenAI","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Message"],"selected":"Message","name":"text_output","display_name":"Text","method":"text_response","value":"__UNDEFINED__","cache":true},{"types":["LanguageModel"],"selected":"LanguageModel","name":"model_output","display_name":"Language Model","method":"build_model","value":"__UNDEFINED__","cache":true}],"field_order":["input_value","system_message","stream","max_tokens","model_kwargs","json_mode","output_schema","model_name","openai_api_base","api_key","temperature","seed"],"beta":false,"edited":false,"lf_version":"1.0.17"},"id":"OpenAIModel-BJWIg"},"selected":false,"width":384,"height":433,"positionAbsolute":{"x":1718.9773974162958,"y":603.4642741725065},"dragging":false},{"id":"Memory-CTQWu","type":"genericNode","position":{"x":1240.7186213296432,"y":1059.5754404393747},"data":{"type":"Memory","node":{"template":{"_type":"Component","memory":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"memory","value":"","display_name":"External Memory","advanced":true,"input_types":["BaseChatMessageHistory"],"dynamic":false,"info":"Retrieve messages from an external memory. If empty, it will use the Langflow tables.","title_case":false,"type":"other","_input_type":"HandleInput"},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langchain.memory import ConversationBufferMemory\n\nfrom langflow.custom import Component\nfrom langflow.field_typing import BaseChatMemory\nfrom langflow.helpers.data import data_to_text\nfrom langflow.inputs import HandleInput\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import LCBuiltinChatMemory, get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages from Langflow tables or an external memory.\"\n icon = \"message-square-more\"\n name = \"Memory\"\n\n inputs = [\n HandleInput(\n name=\"memory\",\n display_name=\"External Memory\",\n input_types=[\"BaseChatMessageHistory\"],\n info=\"Retrieve messages from an external memory. If empty, it will use the Langflow tables.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Filter by sender type.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Filter by sender name.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Messages (Data)\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n Output(display_name=\"Memory\", name=\"lc_memory\", method=\"build_lc_memory\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n if self.memory:\n # override session_id\n self.memory.session_id = session_id\n\n stored = self.memory.messages\n # langchain memories are supposed to return messages in ascending order\n if order == \"DESC\":\n stored = stored[::-1]\n if n_messages:\n stored = stored[:n_messages]\n stored = [Message.from_lc_message(m) for m in stored]\n if sender:\n expected_type = MESSAGE_SENDER_AI if sender == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER\n stored = [m for m in stored if m.type == expected_type]\n else:\n stored = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = stored\n return stored\n\n def retrieve_messages_as_text(self) -> Message:\n stored_text = data_to_text(self.template, self.retrieve_messages())\n self.status = stored_text\n return Message(text=stored_text)\n\n def build_lc_memory(self) -> BaseChatMemory:\n if self.memory:\n chat_memory = self.memory\n else:\n chat_memory = LCBuiltinChatMemory(flow_id=self.flow_id, session_id=self.session_id)\n return ConversationBufferMemory(chat_memory=chat_memory)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"n_messages":{"trace_as_metadata":true,"list":false,"required":false,"placeholder":"","show":true,"name":"n_messages","value":100,"display_name":"Number of Messages","advanced":true,"dynamic":false,"info":"Number of messages to retrieve.","title_case":false,"type":"int","_input_type":"IntInput"},"order":{"trace_as_metadata":true,"options":["Ascending","Descending"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"order","value":"Ascending","display_name":"Order","advanced":true,"dynamic":false,"info":"Order of the messages.","title_case":false,"type":"str","_input_type":"DropdownInput"},"sender":{"trace_as_metadata":true,"options":["Machine","User","Machine and User"],"combobox":false,"required":false,"placeholder":"","show":true,"name":"sender","value":"Machine and User","display_name":"Sender Type","advanced":true,"dynamic":false,"info":"Filter by sender type.","title_case":false,"type":"str","_input_type":"DropdownInput"},"sender_name":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"sender_name","value":"","display_name":"Sender Name","advanced":true,"input_types":["Message"],"dynamic":false,"info":"Filter by sender name.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"session_id":{"trace_as_input":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"session_id","value":"","display_name":"Session ID","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The session ID of the chat. If empty, the current session ID parameter will be used.","title_case":false,"type":"str","_input_type":"MessageTextInput"},"template":{"trace_as_input":true,"multiline":true,"trace_as_metadata":true,"load_from_db":false,"list":false,"required":false,"placeholder":"","show":true,"name":"template","value":"{sender_name}: {text}","display_name":"Template","advanced":true,"input_types":["Message"],"dynamic":false,"info":"The template to use for formatting the data. It can contain the keys {text}, {sender} or any other key in the message data.","title_case":false,"type":"str","_input_type":"MultilineInput"}},"description":"Retrieves stored chat messages from Langflow tables or an external memory.","icon":"message-square-more","base_classes":["BaseChatMemory","Data","Message"],"display_name":"Chat Memory","documentation":"","custom_fields":{},"output_types":[],"pinned":false,"conditional_paths":[],"frozen":false,"outputs":[{"types":["Data"],"selected":"Data","name":"messages","display_name":"Messages (Data)","method":"retrieve_messages","value":"__UNDEFINED__","cache":true},{"types":["Message"],"selected":"Message","name":"messages_text","display_name":"Messages (Text)","method":"retrieve_messages_as_text","value":"__UNDEFINED__","cache":true,"hidden":true},{"types":["BaseChatMemory"],"selected":"BaseChatMemory","name":"lc_memory","display_name":"Memory","method":"build_lc_memory","value":"__UNDEFINED__","cache":true,"hidden":true}],"field_order":["memory","sender","sender_name","n_messages","session_id","order","template"],"beta":false,"edited":false,"lf_version":"1.0.17"},"id":"Memory-CTQWu"},"selected":false,"width":384,"height":244,"dragging":false,"positionAbsolute":{"x":1240.7186213296432,"y":1059.5754404393747}},{"id":"Prompt-0dWZu","type":"genericNode","position":{"x":1227.4862876736101,"y":616.3826667128244},"data":{"type":"Prompt","node":{"template":{"_type":"Component","code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"from langflow.base.prompts.api_utils import process_prompt_template\nfrom langflow.custom import Component\nfrom langflow.inputs.inputs import DefaultPromptField\nfrom langflow.io import Output, PromptInput\nfrom langflow.schema.message import Message\nfrom langflow.template.utils import update_template_values\n\n\nclass PromptComponent(Component):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n trace_type = \"prompt\"\n name = \"Prompt\"\n\n inputs = [\n PromptInput(name=\"template\", display_name=\"Template\"),\n ]\n\n outputs = [\n Output(display_name=\"Prompt Message\", name=\"prompt\", method=\"build_prompt\"),\n ]\n\n async def build_prompt(\n self,\n ) -> Message:\n prompt = Message.from_template_and_variables(**self._attributes)\n self.status = prompt.text\n return prompt\n\n def _update_template(self, frontend_node: dict):\n prompt_template = frontend_node[\"template\"][\"template\"][\"value\"]\n custom_fields = frontend_node[\"custom_fields\"]\n frontend_node_template = frontend_node[\"template\"]\n _ = process_prompt_template(\n template=prompt_template,\n name=\"template\",\n custom_fields=custom_fields,\n frontend_node_template=frontend_node_template,\n )\n return frontend_node\n\n def post_code_processing(self, new_frontend_node: dict, current_frontend_node: dict):\n \"\"\"\n This function is called after the code validation is done.\n \"\"\"\n frontend_node = super().post_code_processing(new_frontend_node, current_frontend_node)\n template = frontend_node[\"template\"][\"template\"][\"value\"]\n # Kept it duplicated for backwards compatibility\n _ = process_prompt_template(\n template=template,\n name=\"template\",\n custom_fields=frontend_node[\"custom_fields\"],\n frontend_node_template=frontend_node[\"template\"],\n )\n # Now that template is updated, we need to grab any values that were set in the current_frontend_node\n # and update the frontend_node with those values\n update_template_values(new_template=frontend_node, previous_template=current_frontend_node[\"template\"])\n return frontend_node\n\n def _get_fallback_input(self, **kwargs):\n return DefaultPromptField(**kwargs)\n","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"template":{"trace_as_input":true,"list":false,"required":false,"placeholder":"","show":true,"name":"template","value":"
Before using this flow, ensure you have obtained the necessary API keys from Notion and OpenAI. These keys are essential for the flow to function properly. Keep them secure and do not share them publicly.
To run the Notion Agent for Meeting Notes: