During the flow creation process, you will notice handles (colored circles)
@@ -55,7 +84,7 @@ A component is a building block of a flow.
+## Collection
+
+A collection is a snapshot of flows available in a database.
+
+Collections can be downloaded to local storage and uploaded for future use.
+
+
+
+## Project
+
+A **Project** can be a flow or a component. To view your saved projects, select **My Collection**.
+
+Your **Projects** are displayed.
+
+Click the ** Playground** button to run a flow from the **My Collection** screen.
+
+In the top left corner of the screen are options for **Download Collection**, **Upload Collection**, and **New Project**.
+
+Select **Download Collection** to save your project to your local machine. This downloads all flows and components as a `.json` file.
+
+Select **Upload Collection** to upload a flow or component `.json` file from your local machine.
+
+Select **New Project** to create a new project. In addition to a blank canvas, [starter projects](../starter-projects/basic-prompting.mdx) are also available.
+
## Project options menu
To see options for your project, in the upper left corner of the canvas, select the dropdown menu.
diff --git a/docs/docs/getting-started/flows-components-collections.mdx b/docs/docs/getting-started/flows-components-collections.mdx
index a1e7f95a8..62e87edbd 100644
--- a/docs/docs/getting-started/flows-components-collections.mdx
+++ b/docs/docs/getting-started/flows-components-collections.mdx
@@ -17,25 +17,11 @@ A [project](#project) can be a component or a flow. Projects are saved as part o
For example, the **OpenAI LLM** is a **component** of the **Basic prompting** flow, and the **flow** is stored in a **collection**.
-## Flow
-A **flow** is a pipeline of components connected together in the Langflow canvas.
-
-For example, the [Basic prompting](../starter-projects/basic-prompting.mdx) flow is a pipeline of four components:
-
-
-
-For example, the **OpenAI LLM component** receives input (left side) and produces output (right side) - in this case, receiving input from the **Chat Input** and **Prompt** components and producing output to the **Chat Output** component.
## Component
+
Components are the building blocks of flows. They consist of inputs, outputs, and parameters that define their functionality. These elements provide a convenient and straightforward way to compose LLM-based applications. Learn more about components and how they work in the LangChain [documentation](https://python.langchain.com/docs/integrations/components).
@@ -108,8 +94,5 @@ Click the ** Playground** button to run
In the top left corner of the screen are options for **Download Collection**, **Upload Collection**, and **New Project**.
-Select **Download Collection** to save your project to your local machine. This downloads all flows and components as a `.json` file.
-Select **Upload Collection** to upload a flow or component `.json` file from your local machine.
-Select **New Project** to create a new project. In addition to a blank canvas, [starter projects](../starter-projects/basic-prompting.mdx) are also available.
diff --git a/docs/docs/getting-started/huggingface-spaces.mdx b/docs/docs/getting-started/huggingface-spaces.mdx
deleted file mode 100644
index d2eccc782..000000000
--- a/docs/docs/getting-started/huggingface-spaces.mdx
+++ /dev/null
@@ -1,38 +0,0 @@
-import ThemedImage from "@theme/ThemedImage";
-import useBaseUrl from "@docusaurus/useBaseUrl";
-import ZoomableImage from "/src/theme/ZoomableImage.js";
-import Admonition from "@theme/Admonition";
-
-# π€ HuggingFace Spaces
-
-HuggingFace provides a great alternative for running Langflow in their Spaces environment. This means you can run Langflow without any local installation required.
-
-In a Chromium-based browser, go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow?duplicate=true) or [Langflow v1.0 alpha Preview Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true).
-
-You'll be presented with the following screen:
-
-
-
-Name your Space, define the visibility (Public or Private), and click on **Duplicate Space** to start the installation process. When installation is finished, you'll be redirected to the Space's main page to start using Langflow right away!
-
-## Run a starter project
-
-Langflow provides a range of example flows to help you get started.
-
-Once you get Langflow running in your Space, click on **New Project** in the top right corner of the screen.
-
-Select a starter project from the list, set up your API keys, and click β‘ Run. This will open up Langflow's Interaction Panel with the chat console, text inputs, and outputs ready to go.
-
-For more information on the starter projects, see the guides below:
-
-* [Basic prompting](/starter-projects/basic-prompting.mdx)
-* [Memory chatbot](/starter-projects/memory-chatbot.mdx)
-* [Blog writer](/starter-projects/blog-writer.mdx)
-* [Document QA](/starter-projects/document-qa.mdx)
\ No newline at end of file
diff --git a/docs/docs/getting-started/install-langflow.mdx b/docs/docs/getting-started/install-langflow.mdx
index 7a567d597..d78514909 100644
--- a/docs/docs/getting-started/install-langflow.mdx
+++ b/docs/docs/getting-started/install-langflow.mdx
@@ -6,9 +6,7 @@ import Admonition from "@theme/Admonition";
# π¦ Install Langflow
-
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](./huggingface-spaces) to install it locally.
-
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true), to create your own Langflow workspace in minutes.
Langflow requires [Python 3.10](https://www.python.org/downloads/release/python-3100/) and [pip](https://pypi.org/project/pip/) or [pipx](https://pipx.pypa.io/stable/installation/) to be installed on your system.
@@ -66,4 +64,23 @@ python -m langflow run
β Collaborate, and contribute at our GitHub Repo π β
```
-3. Continue on to the [Quickstart](./quickstart.mdx).
\ No newline at end of file
+3. Continue on to the [Quickstart](./quickstart.mdx).
+
+## HuggingFace Spaces
+
+HuggingFace provides a great alternative for running Langflow in their Spaces environment. This means you can run Langflow without any local installation required.
+
+In a Chromium-based browser, go to the [Langflow Space](https://huggingface.co/spaces/Langflow/Langflow?duplicate=true) or [Langflow v1.0 alpha Preview Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true).
+
+You'll be presented with the following screen:
+
+
+
+Name your Space, define the visibility (Public or Private), and click on **Duplicate Space** to start the installation process. When installation is finished, you'll be redirected to the Space's main page to start using Langflow right away!
\ No newline at end of file
diff --git a/docs/docs/getting-started/quickstart.mdx b/docs/docs/getting-started/quickstart.mdx
index f54a07747..ef7d373a6 100644
--- a/docs/docs/getting-started/quickstart.mdx
+++ b/docs/docs/getting-started/quickstart.mdx
@@ -10,12 +10,12 @@ This guide demonstrates how to build a basic prompt flow and modify that prompt
## Prerequisites
-* [Langflow installed](./install-langflow.mdx)
+* [Langflow installed and running](./install-langflow.mdx)
* [OpenAI API key](https://platform.openai.com)
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](./huggingface-spaces) to install it locally.
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
## Hello World - Basic Prompting
diff --git a/docs/docs/index.mdx b/docs/docs/index.mdx
index e807ee086..7fb912e98 100644
--- a/docs/docs/index.mdx
+++ b/docs/docs/index.mdx
@@ -26,9 +26,11 @@ Its intuitive interface allows for easy manipulation of AI building blocks, enab
- [Quickstart](/getting-started/quickstart) - Create a flow and run it.
-- [HuggingFace Spaces](/getting-started/huggingface-spaces) - Duplicate the Langflow preview space and try it out before you install.
+- [Langflow Canvas](/getting-started/canvas) - Learn more about the Langflow canvas.
-- [New to LLMs?](/getting-started/new-to-llms) - Learn more about LLMs, prompting, and more at [promptingguide.ai](https://promptingguide.ai).
+
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
+
## Learn more about Langflow 1.0
diff --git a/docs/docs/integrations/notion/add-content-to-page.md b/docs/docs/integrations/notion/add-content-to-page.md
new file mode 100644
index 000000000..83b395fd0
--- /dev/null
+++ b/docs/docs/integrations/notion/add-content-to-page.md
@@ -0,0 +1,138 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Add Content To Page
+
+The `AddContentToPage` component converts markdown text to Notion blocks and appends them to a Notion page.
+
+[Notion Reference](https://developers.notion.com/reference/patch-block-children)
+
+
+
+The `AddContentToPage` component enables you to:
+
+- Convert markdown text to Notion blocks.
+- Append the converted blocks to a specified Notion page.
+- Seamlessly integrate Notion content creation into Langflow workflows.
+
+
+## Component Usage
+
+To use the `AddContentToPage` component in a Langflow flow:
+
+1. **Add the `AddContentToPage` component** to your flow.
+2. **Configure the component** by providing:
+ - `markdown_text`: The markdown text to convert.
+ - `block_id`: The ID of the Notion page/block to append the content.
+ - `notion_secret`: The Notion integration token for authentication.
+3. **Connect the component** to other nodes in your flow as needed.
+4. **Run the flow** to convert the markdown text and append it to the specified Notion page.
+
+## Component Python Code
+
+```python
+import json
+from typing import Optional
+
+import requests
+from langflow.custom import CustomComponent
+
+
+class NotionPageCreator(CustomComponent):
+ display_name = "Create Page [Notion]"
+ description = "A component for creating Notion pages."
+ documentation: str = "https://docs.langflow.org/integrations/notion/add-content-to-page"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "database_id": {
+ "display_name": "Database ID",
+ "field_type": "str",
+ "info": "The ID of the Notion database.",
+ },
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ "properties": {
+ "display_name": "Properties",
+ "field_type": "str",
+ "info": "The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}",
+ },
+ }
+
+ def build(
+ self,
+ database_id: str,
+ notion_secret: str,
+ properties: str = '{"Task name": {"id": "title", "type": "title", "title": [{"type": "text", "text": {"content": "Send Notion Components to LF", "link": null}}]}}',
+ ) -> str:
+ if not database_id or not properties:
+ raise ValueError("Invalid input. Please provide 'database_id' and 'properties'.")
+
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Content-Type": "application/json",
+ "Notion-Version": "2022-06-28",
+ }
+
+ data = {
+ "parent": {"database_id": database_id},
+ "properties": json.loads(properties),
+ }
+
+ response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data)
+
+ if response.status_code == 200:
+ page_id = response.json()["id"]
+ self.status = f"Successfully created Notion page with ID: {page_id}\n {str(response.json())}"
+ return response.json()
+ else:
+ error_message = f"Failed to create Notion page. Status code: {response.status_code}, Error: {response.text}"
+ self.status = error_message
+ raise Exception(error_message)
+```
+
+## Example Usage
+
+
+
+Example of using the `AddContentToPage` component in a Langflow flow using Markdown as input:
+
+
+
+In this example, the `AddContentToPage` component connects to a `MarkdownLoader` component to provide the markdown text input. The converted Notion blocks are appended to the specified Notion page using the provided `block_id` and `notion_secret`.
+
+
+
+## Best Practices
+
+When using the `AddContentToPage` component:
+
+- Ensure markdown text is well-formatted.
+- Verify the `block_id` corresponds to the right Notion page/block.
+- Keep your Notion integration token secure.
+- Test with sample markdown text before production use.
+
+The `AddContentToPage` component is a powerful tool for integrating Notion content creation into Langflow workflows, facilitating easy conversion of markdown text to Notion blocks and appending them to specific pages.
+
+## Troubleshooting
+
+If you encounter any issues while using the `AddContentToPage` component, consider the following:
+- Verify the Notion integration tokenβs validity and permissions.
+- Check the Notion API documentation for updates.
+- Ensure markdown text is properly formatted.
+- Double-check the `block_id` for correctness.
+
diff --git a/docs/docs/integrations/notion/intro.md b/docs/docs/integrations/notion/intro.md
new file mode 100644
index 000000000..ec8738dc7
--- /dev/null
+++ b/docs/docs/integrations/notion/intro.md
@@ -0,0 +1,43 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Introduction to Notion in Langflow
+
+The Notion integration in Langflow enables seamless connectivity with Notion databases, pages, and users, facilitating automation and improving productivity.
+
+
+
+####
Download Notion Components Bundle
+
+### Key Features of Notion Integration in Langflow
+
+- **List Pages**: Retrieve a list of pages from a Notion database and access data stored in your Notion workspace.
+- **List Database Properties**: Obtain insights into the properties of a Notion database, allowing for easy understanding of its structure and metadata.
+- **Add Page Content**: Programmatically add new content to a Notion page, simplifying the creation and updating of pages.
+- **List Users**: Retrieve a list of users with access to a Notion workspace, aiding in user management and collaboration.
+- **Update Property**: Update the value of a specific property in a Notion page, enabling easy modification and maintenance of Notion data.
+
+### Potential Use Cases for Notion Integration in Langflow
+
+- **Task Automation**: Automate task creation in Notion using Langflow's AI capabilities. Describe the required tasks, and they will be automatically created and updated in Notion.
+- **Context Extraction from Meetings**: Leverage AI to analyze meeting contexts, extract key points, and update the relevant Notion pages automatically.
+- **Content Creation**: Utilize AI to generate ideas, suggest templates, and populate Notion pages with relevant data, enhancing content management efficiency.
+
+### Getting Started with Notion Integration in Langflow
+
+1. **Set Up Notion Integration**: Follow the guide [Setting up a Notion App](./setup) to set up a Notion integration in your workspace.
+2. **Configure Notion Components**: Provide the necessary authentication details and parameters to configure the Notion components in your Langflow flows.
+3. **Connect Components**: Integrate Notion components with other Langflow components to build your workflow.
+4. **Test and Refine**: Ensure your Langflow flow operates as intended by testing and refining it.
+5. **Deploy and Run**: Deploy your Langflow flow to automate Notion-related tasks and processes.
+
+The Notion integration in Langflow offers a powerful toolset for automation and productivity enhancement. Whether managing tasks, extracting meeting insights, or creating content, Langflow and Notion provide robust solutions for streamlining workflows.
diff --git a/docs/docs/integrations/notion/list-database-properties.md b/docs/docs/integrations/notion/list-database-properties.md
new file mode 100644
index 000000000..830ea3324
--- /dev/null
+++ b/docs/docs/integrations/notion/list-database-properties.md
@@ -0,0 +1,115 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Database Properties
+
+The `NotionDatabaseProperties` component retrieves properties of a Notion database. It provides a convenient way to integrate Notion database information into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/post-database-query)
+
+
+The `NotionDatabaseProperties` component enables you to:
+- Retrieve properties of a Notion database
+- Access the retrieved properties in your Langflow flows
+- Integrate Notion database information seamlessly into your workflows
+
+
+## Component Usage
+
+To use the `NotionDatabaseProperties` component in a Langflow flow, follow these steps:
+
+1. Add the `NotionDatabaseProperties` component to your flow.
+2. Configure the component by providing the required inputs:
+ - `database_id`: The ID of the Notion database you want to retrieve properties from.
+ - `notion_secret`: The Notion integration token for authentication.
+3. Connect the output of the `NotionDatabaseProperties` component to other components in your flow as needed.
+
+## Component Python code
+
+```python
+import requests
+from typing import Dict
+
+from langflow import CustomComponent
+from langflow.schema import Record
+
+
+class NotionDatabaseProperties(CustomComponent):
+ display_name = "List Database Properties [Notion]"
+ description = "Retrieve properties of a Notion database."
+ documentation: str = "https://docs.langflow.org/integrations/notion/list-database-properties"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "database_id": {
+ "display_name": "Database ID",
+ "field_type": "str",
+ "info": "The ID of the Notion database.",
+ },
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ }
+
+ def build(
+ self,
+ database_id: str,
+ notion_secret: str,
+ ) -> Record:
+ url = f"https://api.notion.com/v1/databases/{database_id}"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Notion-Version": "2022-06-28", # Use the latest supported version
+ }
+
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+
+ data = response.json()
+ properties = data.get("properties", {})
+
+ record = Record(text=str(response.json()), data=properties)
+ self.status = f"Retrieved {len(properties)} properties from the Notion database.\n {record.text}"
+ return record
+```
+
+## Example Usage
+
+Here's an example of how you can use the `NotionDatabaseProperties` component in a Langflow flow:
+
+
+
+In this example, the `NotionDatabaseProperties` component retrieves the properties of a Notion database, and the retrieved properties are then used as input for subsequent components in the flow.
+
+
+## Best Practices
+
+When using the `NotionDatabaseProperties` component, consider the following best practices:
+
+- Ensure that you have a valid Notion integration token with the necessary permissions to access the desired database.
+- Double-check the database ID to avoid retrieving properties from the wrong database.
+- Handle potential errors gracefully by checking the response status and providing appropriate error messages.
+
+The `NotionDatabaseProperties` component simplifies the process of retrieving properties from a Notion database and integrating them into your Langflow workflows. By leveraging this component, you can easily access and utilize Notion database information in your flows, enabling powerful integrations and automations.
+
+Feel free to explore the capabilities of the `NotionDatabaseProperties` component and experiment with different use cases to enhance your Langflow workflows!
+
+## Troubleshooting
+
+If you encounter any issues while using the `NotionDatabaseProperties` component, consider the following:
+- Verify that the Notion integration token is valid and has the required permissions.
+- Check the database ID to ensure it matches the intended Notion database.
+- Inspect the response from the Notion API for any error messages or status codes that may indicate the cause of the issue.
\ No newline at end of file
diff --git a/docs/docs/integrations/notion/list-pages.md b/docs/docs/integrations/notion/list-pages.md
new file mode 100644
index 000000000..3e219870e
--- /dev/null
+++ b/docs/docs/integrations/notion/list-pages.md
@@ -0,0 +1,178 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# List Pages
+
+The `NotionListPages` component queries a Notion database with filtering and sorting. It provides a convenient way to integrate Notion database querying capabilities into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/post-database-query)
+
+
+ The `NotionListPages` component enables you to:
+
+- Query a Notion database with custom filters and sorting options
+- Retrieve specific pages from a Notion database based on the provided criteria
+- Integrate Notion database data seamlessly into your Langflow workflows
+
+
+
+## Component Usage
+
+To use the `NotionListPages
+` component in a Langflow flow, follow these steps:
+
+1. **Add the `NotionListPages
+` component to your flow.**
+2. **Configure the component by providing the required parameters:**
+ - `notion_secret`: The Notion integration token for authentication.
+ - `database_id`: The ID of the Notion database you want to query.
+ - `query_payload`: A JSON string containing the filters and sorting options for the query.
+3. **Connect the `NotionListPages
+` component to other components in your flow as needed.**
+
+## Component Python code
+
+```python
+import requests
+import json
+from typing import Dict, Any, List
+from langflow.custom import CustomComponent
+from langflow.schema import Record
+
+class NotionListPages(CustomComponent):
+ display_name = "List Pages [Notion]"
+ 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"}]}'
+ )
+ documentation: str = "https://docs.langflow.org/integrations/notion/list-pages"
+ icon = "NotionDirectoryLoader"
+
+ field_order = [
+ "notion_secret",
+ "database_id",
+ "query_payload",
+ ]
+
+ def build_config(self):
+ return {
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ "database_id": {
+ "display_name": "Database ID",
+ "field_type": "str",
+ "info": "The ID of the Notion database to query.",
+ },
+ "query_payload": {
+ "display_name": "Database query",
+ "field_type": "str",
+ "info": "A JSON string containing the filters that will be used for querying the database. EG: {'filter': {'property': 'Status', 'status': {'equals': 'In progress'}}}",
+ },
+ }
+
+ def build(
+ self,
+ notion_secret: str,
+ database_id: str,
+ query_payload: str = "{}",
+ ) -> List[Record]:
+ try:
+ query_data = json.loads(query_payload)
+ filter_obj = query_data.get("filter")
+ sorts = query_data.get("sorts", [])
+
+ url = f"https://api.notion.com/v1/databases/{database_id}/query"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Content-Type": "application/json",
+ "Notion-Version": "2022-06-28",
+ }
+
+ data = {
+ "sorts": sorts,
+ }
+
+ if filter_obj:
+ data["filter"] = filter_obj
+
+ response = requests.post(url, headers=headers, json=data)
+ response.raise_for_status()
+
+ results = response.json()
+ records = []
+ combined_text = f"Pages found: {len(results['results'])}\n\n"
+ for page in results['results']:
+ page_data = {
+ 'id': page['id'],
+ 'url': page['url'],
+ 'created_time': page['created_time'],
+ 'last_edited_time': page['last_edited_time'],
+ 'properties': page['properties'],
+ }
+
+ text = (
+ f"id: {page['id']}\n"
+ f"url: {page['url']}\n"
+ f"created_time: {page['created_time']}\n"
+ f"last_edited_time: {page['last_edited_time']}\n"
+ f"properties: {json.dumps(page['properties'], indent=2)}\n\n"
+ )
+
+ combined_text += text
+ records.append(Record(text=text, data=page_data))
+
+ self.status = combined_text.strip()
+ return records
+
+ except Exception as e:
+ self.status = f"An error occurred: {str(e)}"
+ return [Record(text=self.status, data=[])]
+```
+
+
+
+## Example Usage
+Here's an example of how you can use the `NotionListPages` component in a Langflow flow and passing to the Prompt component:
+
+
+
+In this example, the `NotionListPages` component is used to retrieve specific pages from a Notion database based on the provided filters and sorting options. The retrieved data can then be processed further in the subsequent components of the flow.
+
+
+## Best Practices
+
+ When using the `NotionListPages
+` component, consider the following best practices:
+
+- Ensure that you have a valid Notion integration token with the necessary permissions to query the desired database.
+- Construct the `query_payload` JSON string carefully, following the Notion API documentation for filtering and sorting options.
+
+The `NotionListPages
+` component provides a powerful way to integrate Notion database querying capabilities into your Langflow workflows. By leveraging this component, you can easily retrieve specific pages from a Notion database based on custom filters and sorting options, enabling you to build more dynamic and data-driven flows.
+
+We encourage you to explore the capabilities of the `NotionListPages
+` component further and experiment with different querying scenarios to unlock the full potential of integrating Notion databases into your Langflow workflows.
+
+## Troubleshooting
+
+ If you encounter any issues while using the `NotionListPages` component, consider the following:
+
+- Double-check that the `notion_secret` and `database_id` are correct and valid.
+- Verify that the `query_payload` JSON string is properly formatted and contains valid filtering and sorting options.
+- Check the Notion API documentation for any updates or changes that may affect the component's functionality.
diff --git a/docs/docs/integrations/notion/list-users.md b/docs/docs/integrations/notion/list-users.md
new file mode 100644
index 000000000..90761239a
--- /dev/null
+++ b/docs/docs/integrations/notion/list-users.md
@@ -0,0 +1,127 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# User List
+
+The `NotionUserList` component retrieves users from Notion. It provides a convenient way to integrate Notion user data into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/get-users)
+
+
+ The `NotionUserList` component enables you to:
+
+- Retrieve user data from Notion
+- Access user information such as ID, type, name, and avatar URL
+- Integrate Notion user data seamlessly into your Langflow workflows
+
+
+## Component Usage
+
+To use the `NotionUserList` component in a Langflow flow, follow these steps:
+
+1. Add the `NotionUserList` component to your flow.
+2. Configure the component by providing the required Notion secret token.
+3. Connect the component to other nodes in your flow as needed.
+
+## Component Python code
+
+```python
+import requests
+from typing import List
+
+from langflow import CustomComponent
+from langflow.schema import Record
+
+
+class NotionUserList(CustomComponent):
+ display_name = "List Users [Notion]"
+ description = "Retrieve users from Notion."
+ documentation: str = "https://docs.langflow.org/integrations/notion/list-users"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ }
+
+ def build(
+ self,
+ notion_secret: str,
+ ) -> List[Record]:
+ url = "https://api.notion.com/v1/users"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Notion-Version": "2022-06-28",
+ }
+
+ response = requests.get(url, headers=headers)
+ response.raise_for_status()
+
+ data = response.json()
+ results = data['results']
+
+ records = []
+ for user in results:
+ id = user['id']
+ type = user['type']
+ name = user.get('name', '')
+ avatar_url = user.get('avatar_url', '')
+
+ record_data = {
+ "id": id,
+ "type": type,
+ "name": name,
+ "avatar_url": avatar_url,
+ }
+
+ output = "User:\n"
+ for key, value in record_data.items():
+ output += f"{key.replace('_', ' ').title()}: {value}\n"
+ output += "________________________\n"
+
+ record = Record(text=output, data=record_data)
+ records.append(record)
+
+ self.status = "\n".join(record.text for record in records)
+ return records
+```
+
+## Example Usage
+
+Here's an example of how you can use the `NotionUserList` component in a Langflow flow and passing the outputs to the Prompt component:
+
+
+
+
+
+## Best Practices
+
+ When using the `NotionUserList` component, consider the following best practices:
+
+- Ensure that you have a valid Notion integration token with the necessary permissions to retrieve user data.
+- Handle the retrieved user data securely and in compliance with Notion's API usage guidelines.
+
+The `NotionUserList` component provides a seamless way to integrate Notion user data into your Langflow workflows. By leveraging this component, you can easily retrieve and utilize user information from Notion, enhancing the capabilities of your Langflow applications. Feel free to explore and experiment with the `NotionUserList` component to unlock new possibilities in your Langflow projects!
+
+
+## Troubleshooting
+
+ If you encounter any issues while using the `NotionUserList` component, consider the following:
+
+- Double-check that your Notion integration token is valid and has the required permissions.
+- Verify that you have installed the necessary dependencies (`requests`) for the component to function properly.
+- Check the Notion API documentation for any updates or changes that may affect the component's functionality.
\ No newline at end of file
diff --git a/docs/docs/integrations/notion/page-content-viewer.md b/docs/docs/integrations/notion/page-content-viewer.md
new file mode 100644
index 000000000..a38c05fd0
--- /dev/null
+++ b/docs/docs/integrations/notion/page-content-viewer.md
@@ -0,0 +1,142 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Page Content
+
+The `NotionPageContent` component retrieves the content of a Notion page as plain text. It provides a convenient way to integrate Notion page content into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/get-page)
+
+
+
+ The `NotionPageContent` component enables you to:
+
+- Retrieve the content of a Notion page as plain text
+- Extract text from various block types, including paragraphs, headings, lists, and more
+- Integrate Notion page content seamlessly into your Langflow workflows
+
+
+
+## Component Usage
+
+To use the `NotionPageContent` component in a Langflow flow, follow these steps:
+
+1. Add the `NotionPageContent` component to your flow.
+2. Configure the component by providing the required inputs:
+ - `page_id`: The ID of the Notion page you want to retrieve.
+ - `notion_secret`: Your Notion integration token for authentication.
+3. Connect the output of the `NotionPageContent` component to other components in your flow as needed.
+
+## Component Python code
+
+```python
+import requests
+from typing import Dict, Any
+
+from langflow import CustomComponent
+from langflow.schema import Record
+
+
+class NotionPageContent(CustomComponent):
+ display_name = "Page Content Viewer [Notion]"
+ description = "Retrieve the content of a Notion page as plain text."
+ documentation: str = "https://docs.langflow.org/integrations/notion/page-content-viewer"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "page_id": {
+ "display_name": "Page ID",
+ "field_type": "str",
+ "info": "The ID of the Notion page to retrieve.",
+ },
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ }
+
+ def build(
+ self,
+ page_id: str,
+ notion_secret: str,
+ ) -> Record:
+ blocks_url = f"https://api.notion.com/v1/blocks/{page_id}/children?page_size=100"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Notion-Version": "2022-06-28", # Use the latest supported version
+ }
+
+ # Retrieve the child blocks
+ blocks_response = requests.get(blocks_url, headers=headers)
+ blocks_response.raise_for_status()
+ blocks_data = blocks_response.json()
+
+ # Parse the blocks and extract the content as plain text
+ content = self.parse_blocks(blocks_data["results"])
+
+ self.status = content
+ return Record(data={"content": content}, text=content)
+
+ def parse_blocks(self, blocks: list) -> str:
+ content = ""
+ for block in blocks:
+ block_type = block["type"]
+ if block_type in ["paragraph", "heading_1", "heading_2", "heading_3", "quote"]:
+ content += self.parse_rich_text(block[block_type]["rich_text"]) + "\n\n"
+ elif block_type in ["bulleted_list_item", "numbered_list_item"]:
+ content += self.parse_rich_text(block[block_type]["rich_text"]) + "\n"
+ elif block_type == "to_do":
+ content += self.parse_rich_text(block["to_do"]["rich_text"]) + "\n"
+ elif block_type == "code":
+ content += self.parse_rich_text(block["code"]["rich_text"]) + "\n\n"
+ elif block_type == "image":
+ content += f"[Image: {block['image']['external']['url']}]\n\n"
+ elif block_type == "divider":
+ content += "---\n\n"
+ return content.strip()
+
+ def parse_rich_text(self, rich_text: list) -> str:
+ text = ""
+ for segment in rich_text:
+ text += segment["plain_text"]
+ return text
+```
+
+## Example Usage
+
+
+
+Here's an example of how you can use the `NotionPageContent` component in a Langflow flow:
+
+
+
+
+## Best Practices
+
+ When using the `NotionPageContent` component, consider the following best practices:
+
+- Ensure that you have the necessary permissions to access the Notion page you want to retrieve.
+- Keep your Notion integration token secure and avoid sharing it publicly.
+- Be mindful of the content you retrieve and ensure that it aligns with your intended use case.
+
+The `NotionPageContent` component provides a seamless way to integrate Notion page content into your Langflow workflows. By leveraging this component, you can easily retrieve and process the content of Notion pages, enabling you to build powerful and dynamic applications. Explore the capabilities of the `NotionPageContent` component and unlock new possibilities in your Langflow projects!
+
+## Troubleshooting
+
+ If you encounter any issues while using the `NotionPageContent` component, consider the following:
+
+- Double-check that you have provided the correct Notion page ID.
+- Verify that your Notion integration token is valid and has the necessary permissions.
+- Check the Notion API documentation for any updates or changes that may affect the component's functionality.
diff --git a/docs/docs/integrations/notion/page-create.md b/docs/docs/integrations/notion/page-create.md
new file mode 100644
index 000000000..0269096b9
--- /dev/null
+++ b/docs/docs/integrations/notion/page-create.md
@@ -0,0 +1,129 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Page Create
+
+The `NotionPageCreator` component creates pages in a Notion database. It provides a convenient way to integrate Notion page creation into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/patch-block-children)
+
+
+The `NotionPageCreator` component enables you to:
+- Create new pages in a specified Notion database
+- Set custom properties for the created pages
+- Retrieve the ID and URL of the newly created pages
+
+
+## Component Usage
+
+To use the `NotionPageCreator` component in a Langflow flow, follow these steps:
+
+1. Add the `NotionPageCreator` component to your flow.
+2. Configure the component by providing the required inputs:
+ - `database_id`: The ID of the Notion database where the pages will be created.
+ - `notion_secret`: The Notion integration token for authentication.
+ - `properties`: The properties of the new page, specified as a JSON string.
+3. Connect the component to other components in your flow as needed.
+4. Run the flow to create Notion pages based on the configured inputs.
+
+## Component Python Code
+
+```python
+import json
+from typing import Optional
+
+import requests
+from langflow.custom import CustomComponent
+
+
+class NotionPageCreator(CustomComponent):
+ display_name = "Create Page [Notion]"
+ description = "A component for creating Notion pages."
+ documentation: str = "https://docs.langflow.org/integrations/notion/page-create"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "database_id": {
+ "display_name": "Database ID",
+ "field_type": "str",
+ "info": "The ID of the Notion database.",
+ },
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ "properties": {
+ "display_name": "Properties",
+ "field_type": "str",
+ "info": "The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}",
+ },
+ }
+
+ def build(
+ self,
+ database_id: str,
+ notion_secret: str,
+ properties: str = '{"Task name": {"id": "title", "type": "title", "title": [{"type": "text", "text": {"content": "Send Notion Components to LF", "link": null}}]}}',
+ ) -> str:
+ if not database_id or not properties:
+ raise ValueError("Invalid input. Please provide 'database_id' and 'properties'.")
+
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Content-Type": "application/json",
+ "Notion-Version": "2022-06-28",
+ }
+
+ data = {
+ "parent": {"database_id": database_id},
+ "properties": json.loads(properties),
+ }
+
+ response = requests.post("https://api.notion.com/v1/pages", headers=headers, json=data)
+
+ if response.status_code == 200:
+ page_id = response.json()["id"]
+ self.status = f"Successfully created Notion page with ID: {page_id}\n {str(response.json())}"
+ return response.json()
+ else:
+ error_message = f"Failed to create Notion page. Status code: {response.status_code}, Error: {response.text}"
+ self.status = error_message
+ raise Exception(error_message)
+```
+
+## Example Usage
+
+Here's an example of how to use the `NotionPageCreator` component in a Langflow flow:
+
+
+
+
+## Best Practices
+
+When using the `NotionPageCreator` component, consider the following best practices:
+
+- Ensure that you have a valid Notion integration token with the necessary permissions to create pages in the specified database.
+- Properly format the `properties` input as a JSON string, matching the structure and field types of your Notion database.
+- Handle any errors or exceptions that may occur during the page creation process and provide appropriate error messages.
+- To avoid the hassle of messing with JSON, we recommend using the LLM to create the JSON for you as input.
+
+The `NotionPageCreator` component simplifies the process of creating pages in a Notion database directly from your Langflow workflows. By leveraging this component, you can seamlessly integrate Notion page creation functionality into your automated processes, saving time and effort. Feel free to explore the capabilities of the `NotionPageCreator` component and adapt it to suit your specific requirements.
+
+## Troubleshooting
+
+If you encounter any issues while using the `NotionPageCreator` component, consider the following:
+- Double-check that the `database_id` and `notion_secret` inputs are correct and valid.
+- Verify that the `properties` input is properly formatted as a JSON string and matches the structure of your Notion database.
+- Check the Notion API documentation for any updates or changes that may affect the component's functionality.
\ No newline at end of file
diff --git a/docs/docs/integrations/notion/page-update.md b/docs/docs/integrations/notion/page-update.md
new file mode 100644
index 000000000..3389f64d3
--- /dev/null
+++ b/docs/docs/integrations/notion/page-update.md
@@ -0,0 +1,139 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Page Update
+
+The `NotionPageUpdate` component updates the properties of a Notion page. It provides a convenient way to integrate updating Notion page properties into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/patch-page)
+
+## Component Usage
+
+To use the `NotionPageUpdate` component in your Langflow flow:
+
+1. Drag and drop the `NotionPageUpdate` component onto the canvas.
+2. Double-click the component to open its configuration.
+3. Provide the required parameters as defined in the component's `build_config` method.
+4. Connect the component to other nodes in your flow as needed.
+
+## Component Python Code
+
+```python
+import json
+import requests
+from typing import Dict, Any
+
+from langflow import CustomComponent
+from langflow.schema import Record
+
+
+class NotionPageUpdate(CustomComponent):
+ display_name = "Update Page Property [Notion]"
+ description = "Update the properties of a Notion page."
+ documentation: str = "https://docs.langflow.org/integrations/notion/page-update"
+ icon = "NotionDirectoryLoader"
+
+ def build_config(self):
+ return {
+ "page_id": {
+ "display_name": "Page ID",
+ "field_type": "str",
+ "info": "The ID of the Notion page to update.",
+ },
+ "properties": {
+ "display_name": "Properties",
+ "field_type": "str",
+ "info": "The properties to update on the page (as a JSON string).",
+ "multiline": True,
+ },
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ }
+
+ def build(
+ self,
+ page_id: str,
+ properties: str,
+ notion_secret: str,
+ ) -> Record:
+ url = f"https://api.notion.com/v1/pages/{page_id}"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Content-Type": "application/json",
+ "Notion-Version": "2022-06-28", # Use the latest supported version
+ }
+
+ try:
+ parsed_properties = json.loads(properties)
+ except json.JSONDecodeError as e:
+ raise ValueError("Invalid JSON format for properties") from e
+
+ data = {
+ "properties": parsed_properties
+ }
+
+ response = requests.patch(url, headers=headers, json=data)
+ response.raise_for_status()
+
+ updated_page = response.json()
+
+ output = "Updated page properties:\n"
+ for prop_name, prop_value in updated_page["properties"].items():
+ output += f"{prop_name}: {prop_value}\n"
+
+ self.status = output
+ return Record(data=updated_page)
+```
+
+Let's break down the key parts of this component:
+
+- The `build_config` method defines the configuration fields for the component. It specifies the required parameters and their properties, such as display names, field types, and any additional information or validation.
+
+- The `build` method contains the main logic of the component. It takes the configured parameters as input and performs the necessary operations to update the properties of a Notion page.
+
+- The component interacts with the Notion API to update the page properties. It constructs the API URL, headers, and request data based on the provided parameters.
+
+- The processed data is returned as a `Record` object, which can be connected to other components in the Langflow flow. The `Record` object contains the updated page data.
+
+- The component also stores the updated page properties in the `status` attribute for logging and debugging purposes.
+
+## Example Usage
+
+
+Here's an example of how to use the `NotionPageUpdate` component in a Langflow flow using:
+
+
+
+
+## Best Practices
+
+When using the `NotionPageUpdate` component, consider the following best practices:
+
+- Ensure that you have a valid Notion integration token with the necessary permissions to update page properties.
+- Handle edge cases and error scenarios gracefully, such as invalid JSON format for properties or API request failures.
+- We recommend using an LLM to generate the inputs for this component, to allow flexibilty
+
+By leveraging the `NotionPageUpdate` component in Langflow, you can easily integrate updating Notion page properties into your language model workflows and build powerful applications that extend Langflow's capabilities.
+
+
+## Troubleshooting
+
+If you encounter any issues while using the `NotionPageUpdate` component, consider the following:
+
+- Double-check that you have correctly configured the component with the required parameters, including the page ID, properties JSON, and Notion integration token.
+- Verify that your Notion integration token has the necessary permissions to update page properties.
+- Check the Langflow logs for any error messages or exceptions related to the component, such as invalid JSON format or API request failures.
+- Consult the [Notion API Documentation](https://developers.notion.com/reference/patch-page) for specific troubleshooting steps or common issues related to updating page properties.
diff --git a/docs/docs/integrations/notion/search.md b/docs/docs/integrations/notion/search.md
new file mode 100644
index 000000000..3ff7472dc
--- /dev/null
+++ b/docs/docs/integrations/notion/search.md
@@ -0,0 +1,183 @@
+import Admonition from "@theme/Admonition";
+import ThemedImage from "@theme/ThemedImage";
+import useBaseUrl from "@docusaurus/useBaseUrl";
+import ZoomableImage from "/src/theme/ZoomableImage.js";
+
+# Notion Search
+
+The `NotionSearch` component is designed to search all pages and databases that have been shared with an integration in Notion. It provides a convenient way to integrate Notion search capabilities into your Langflow workflows.
+
+[Notion Reference](https://developers.notion.com/reference/search)
+
+
+ The `NotionSearch` component enables you to:
+
+- Search for pages and databases in Notion that have been shared with an integration
+- Filter the search results based on object type (pages or databases)
+- Sort the search results in ascending or descending order based on the last edited time
+
+
+
+## Component Usage
+
+To use the `NotionSearch` component in a Langflow flow, follow these steps:
+
+1. **Add the `NotionSearch` component to your flow.**
+2. **Configure the component by providing the required parameters:**
+ - `notion_secret`: The Notion integration token for authentication.
+ - `query`: The text to search for in page and database titles.
+ - `filter_value`: The type of objects to include in the search results (pages or databases).
+ - `sort_direction`: The direction to sort the search results (ascending or descending).
+3. **Connect the `NotionSearch` component to other components in your flow as needed.**
+
+## Component Python Code
+
+```python
+import requests
+from typing import Dict, Any, List
+from langflow.custom import CustomComponent
+from langflow.schema import Record
+
+class NotionSearch(CustomComponent):
+ display_name = "Search Notion"
+ description = (
+ "Searches all pages and databases that have been shared with an integration."
+ )
+ documentation: str = "https://docs.langflow.org/integrations/notion/search"
+ icon = "NotionDirectoryLoader"
+
+ field_order = [
+ "notion_secret",
+ "query",
+ "filter_value",
+ "sort_direction",
+ ]
+
+ def build_config(self):
+ return {
+ "notion_secret": {
+ "display_name": "Notion Secret",
+ "field_type": "str",
+ "info": "The Notion integration token.",
+ "password": True,
+ },
+ "query": {
+ "display_name": "Search Query",
+ "field_type": "str",
+ "info": "The text that the API compares page and database titles against.",
+ },
+ "filter_value": {
+ "display_name": "Filter Type",
+ "field_type": "str",
+ "info": "Limits the results to either only pages or only databases.",
+ "options": ["page", "database"],
+ "default_value": "page",
+ },
+ "sort_direction": {
+ "display_name": "Sort Direction",
+ "field_type": "str",
+ "info": "The direction to sort the results.",
+ "options": ["ascending", "descending"],
+ "default_value": "descending",
+ },
+ }
+
+ def build(
+ self,
+ notion_secret: str,
+ query: str = "",
+ filter_value: str = "page",
+ sort_direction: str = "descending",
+ ) -> List[Record]:
+ try:
+ url = "https://api.notion.com/v1/search"
+ headers = {
+ "Authorization": f"Bearer {notion_secret}",
+ "Content-Type": "application/json",
+ "Notion-Version": "2022-06-28",
+ }
+
+ data = {
+ "query": query,
+ "filter": {
+ "value": filter_value,
+ "property": "object"
+ },
+ "sort":{
+ "direction": sort_direction,
+ "timestamp": "last_edited_time"
+ }
+ }
+
+ response = requests.post(url, headers=headers, json=data)
+ response.raise_for_status()
+
+ results = response.json()
+ records = []
+ combined_text = f"Results found: {len(results['results'])}\n\n"
+ for result in results['results']:
+ result_data = {
+ 'id': result['id'],
+ 'type': result['object'],
+ 'last_edited_time': result['last_edited_time'],
+ }
+
+ if result['object'] == 'page':
+ result_data['title_or_url'] = result['url']
+ text = f"id: {result['id']}\ntitle_or_url: {result['url']}\n"
+ elif result['object'] == 'database':
+ if 'title' in result and isinstance(result['title'], list) and len(result['title']) > 0:
+ result_data['title_or_url'] = result['title'][0]['plain_text']
+ text = f"id: {result['id']}\ntitle_or_url: {result['title'][0]['plain_text']}\n"
+ else:
+ result_data['title_or_url'] = "N/A"
+ text = f"id: {result['id']}\ntitle_or_url: N/A\n"
+
+ text += f"type: {result['object']}\nlast_edited_time: {result['last_edited_time']}\n\n"
+ combined_text += text
+ records.append(Record(text=text, data=result_data))
+
+ self.status = combined_text
+ return records
+
+ except Exception as e:
+ self.status = f"An error occurred: {str(e)}"
+ return [Record(text=self.status, data=[])]
+```
+
+## Example Usage
+
+Here's an example of how you can use the `NotionSearch` component in a Langflow flow:
+
+
+
+In this example, the `NotionSearch` component is used to search for pages and databases in Notion based on the provided query and filter criteria. The retrieved data can then be processed further in the subsequent components of the flow.
+
+
+## Best Practices
+
+When using the `NotionSearch` component, consider these best practices:
+
+- Ensure you have a valid Notion integration token with the necessary permissions to search for pages and databases.
+- Provide a meaningful search query to narrow down the results to the desired pages or databases.
+- Choose the appropriate filter type (`page` or `database`) based on your search requirements.
+- Consider the sorting direction (`ascending` or `descending`) to organize the search results effectively.
+
+The `NotionSearch` component provides a powerful way to integrate Notion search capabilities into your Langflow workflows. By leveraging this component, you can easily search for pages and databases in Notion based on custom queries and filters, enabling you to build more dynamic and data-driven flows.
+
+We encourage you to explore the capabilities of the `NotionSearch` component further and experiment with different search scenarios to unlock the full potential of integrating Notion search into your Langflow workflows.
+
+## Troubleshooting
+
+If you encounter any issues while using the `NotionSearch` component, consider the following:
+
+- Double-check that the `notion_secret` is correct and valid.
+- Verify that the Notion integration has the necessary permissions to access the desired pages and databases.
+- Check the Notion API documentation for any updates or changes that may affect the component's functionality.
diff --git a/docs/docs/integrations/notion/setup.md b/docs/docs/integrations/notion/setup.md
new file mode 100644
index 000000000..9511d9c81
--- /dev/null
+++ b/docs/docs/integrations/notion/setup.md
@@ -0,0 +1,79 @@
+import Admonition from "@theme/Admonition";
+
+# Setting up a Notion App
+
+To use Notion components in Langflow, you first need to create a Notion integration and configure it with the necessary capabilities. This guide will walk you through the process of setting up a Notion integration and granting it access to your Notion databases.
+
+## Prerequisites
+
+- A Notion account with access to the workspace where you want to use the integration.
+- Admin permissions in the Notion workspace to create and manage integrations.
+
+## Step 1: Create a Notion Integration
+
+1. Go to the [Notion Integrations](https://www.notion.com/my-integrations) page.
+2. Click on the "New integration" button.
+3. Give your integration a name and select the workspace where you want to use it.
+4. Click "Submit" to create the integration.
+
+
+When creating the integration, make sure to enable the necessary capabilities based on your requirements. Refer to the [Notion Integration Capabilities](https://developers.notion.com/reference/capabilities) documentation for more information on each capability.
+
+
+## Step 2: Configure Integration Capabilities
+
+After creating the integration, you need to configure its capabilities to define what actions it can perform and what data it can access.
+
+1. In the integration settings page, go to the **Capabilities** tab.
+2. Enable the required capabilities for your integration. For example:
+ - If your integration needs to read data from Notion, enable the "Read content" capability.
+ - If your integration needs to create new content in Notion, enable the "Insert content" capability.
+ - If your integration needs to update existing content in Notion, enable the "Update content" capability.
+3. Configure the user information access level based on your integration's requirements.
+4. Save the changes.
+
+## Step 3: Obtain Integration Token
+
+To authenticate your integration with Notion, you need to obtain an integration token.
+
+1. In the integration settings page, go to the "Secrets" tab.
+2. Copy the "Internal Integration Token" value. This token will be used to authenticate your integration with Notion.
+
+
+Your integration token is a sensitive piece of information. Make sure to keep it secure and never share it publicly. Store it safely in your Langflow configuration or environment variables.
+
+
+## Step 4: Grant Integration Access to Notion Databases
+
+For your integration to interact with Notion databases, you need to grant it access to the specific databases it will be working with.
+
+1. Open the Notion database that you want your integration to access.
+2. Click on the "Share" button in the top-right corner of the page.
+3. In the "Invite" section, select your integration from the list.
+4. Click "Invite" to grant the integration access to the database.
+
+
+If your database contains references to other databases, you need to grant the integration access to those referenced databases as well. Repeat step 4 for each referenced database to ensure your integration has the necessary access.
+
+
+## Using Notion Components in Langflow
+
+Once you have set up your Notion integration and granted it access to the required databases, you can start using the Notion components in Langflow.
+
+Langflow provides the following Notion components:
+
+- **List Pages**: Retrieves a list of pages from a Notion database.
+- **List Database Properties**: Retrieves the properties of a Notion database.
+- **Add Page Content**: Adds content to a Notion page.
+- **List Users**: Retrieves a list of users with access to a Notion workspace.
+- **Update Property**: Updates the value of a property in a Notion page.
+
+Refer to the individual component documentation for more details on how to use each component in your Langflow flows.
+
+## Additional Resources
+
+- [Notion API Documentation](https://developers.notion.com/docs/getting-started)
+- [Notion Integration Capabilities](https://developers.notion.com/reference/capabilities)
+
+If you encounter any issues or have questions, please reach out to our support team or consult the Langflow community forums.
+
diff --git a/docs/docs/starter-projects/basic-prompting.mdx b/docs/docs/starter-projects/basic-prompting.mdx
index ef333643f..6fb7391e2 100644
--- a/docs/docs/starter-projects/basic-prompting.mdx
+++ b/docs/docs/starter-projects/basic-prompting.mdx
@@ -4,7 +4,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
-# Basic prompting
+# Basic Prompting
Prompts serve as the inputs to a large language model (LLM), acting as the interface between human instructions and computational tasks.
@@ -14,36 +14,14 @@ This article demonstrates how to use Langflow's prompt tools to issue basic prom
## Prerequisites
-1. Install Langflow.
-```bash
-python -m pip install langflow --pre
-```
+* [Langflow installed and running](../getting-started/install-langflow.mdx)
-2. Start a local Langflow instance with the Langflow CLI:
-```bash
-langflow run
-```
-Or start Langflow with Python:
-```bash
-python -m langflow run
-```
-
-Result:
-```
-β Welcome to β Langflow β
-β β
-β Access http://127.0.0.1:7860 β
-β Collaborate, and contribute at our GitHub Repo π β
-```
+* [OpenAI API key created](https://platform.openai.com)
-
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
-
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
-3. Create an [OpenAI API key](https://platform.openai.com).
-
## Create the basic prompting project
1. From the Langflow dashboard, click **New Project**.
diff --git a/docs/docs/starter-projects/blog-writer.mdx b/docs/docs/starter-projects/blog-writer.mdx
index 411233c8b..0e8047fd6 100644
--- a/docs/docs/starter-projects/blog-writer.mdx
+++ b/docs/docs/starter-projects/blog-writer.mdx
@@ -4,42 +4,20 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
-# Blog writer
+# Blog Writer
Build a blog writer with OpenAI that uses URLs for reference content.
## Prerequisites
-1. Install Langflow.
-```bash
-python -m pip install langflow --pre
-```
+* [Langflow installed and running](../getting-started/install-langflow.mdx)
-2. Start a local Langflow instance with the Langflow CLI:
-```bash
-langflow run
-```
-Or start Langflow with Python:
-```bash
-python -m langflow run
-```
-
-Result:
-```bash
-β Welcome to β Langflow β
-β β
-β Access http://127.0.0.1:7860 β
-β Collaborate, and contribute at our GitHub Repo π β
-```
+* [OpenAI API key created](https://platform.openai.com)
-
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
-
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
-3. Create an [OpenAI API key](https://platform.openai.com).
-
## Create the Blog Writer project
1. From the Langflow dashboard, click **New Project**.
diff --git a/docs/docs/starter-projects/document-qa.mdx b/docs/docs/starter-projects/document-qa.mdx
index 1807bb948..5e5377355 100644
--- a/docs/docs/starter-projects/document-qa.mdx
+++ b/docs/docs/starter-projects/document-qa.mdx
@@ -10,36 +10,14 @@ Build a question-and-answer chatbot with a document loaded from local memory.
## Prerequisites
-1. Install Langflow.
-```bash
-python -m pip install langflow --pre
-```
+* [Langflow installed and running](../getting-started/install-langflow.mdx)
-2. Start a local Langflow instance with the Langflow CLI:
-```bash
-langflow run
-```
-Or start Langflow with Python:
-```bash
-python -m langflow run
-```
-
-Result:
-```
-β Welcome to β Langflow β
-β β
-β Access http://127.0.0.1:7860 β
-β Collaborate, and contribute at our GitHub Repo π β
-```
+* [OpenAI API key created](https://platform.openai.com)
-
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
-
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
-3. Create an [OpenAI API key](https://platform.openai.com).
-
## Create the Document QA project
1. From the Langflow dashboard, click **New Project**.
diff --git a/docs/docs/starter-projects/memory-chatbot.mdx b/docs/docs/starter-projects/memory-chatbot.mdx
index e9560d9e5..86c64d368 100644
--- a/docs/docs/starter-projects/memory-chatbot.mdx
+++ b/docs/docs/starter-projects/memory-chatbot.mdx
@@ -4,42 +4,20 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
-# Memory chatbot
+# Memory Chatbot
This flow extends the [basic prompting flow](./basic-prompting.mdx) to include chat memory for unique SessionIDs.
## Prerequisites
-1. Install Langflow.
-```bash
-python -m pip install langflow --pre
-```
+* [Langflow installed and running](../getting-started/install-langflow.mdx)
-2. Start a local Langflow instance with the Langflow CLI:
-```bash
-langflow run
-```
-Or start Langflow with Python:
-```bash
-python -m langflow run
-```
-
-Result:
-```
-β Welcome to β Langflow β
-β β
-β Access http://127.0.0.1:7860 β
-β Collaborate, and contribute at our GitHub Repo π β
-```
+* [OpenAI API key created](https://platform.openai.com)
-
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](/getting-started/huggingface-spaces) to install it locally.
-
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
-3. Create an [OpenAI API key](https://platform.openai.com).
-
## Create the memory chatbot project
1. From the Langflow dashboard, click **New Project**.
diff --git a/docs/docs/starter-projects/vector-store-rag.mdx b/docs/docs/starter-projects/vector-store-rag.mdx
index fda7e432b..ddb0a1d46 100644
--- a/docs/docs/starter-projects/vector-store-rag.mdx
+++ b/docs/docs/starter-projects/vector-store-rag.mdx
@@ -4,7 +4,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
import Admonition from "@theme/Admonition";
-# Vector store RAG
+# Vector Store RAG
Retrieval Augmented Generation, or RAG, is a pattern for training LLMs on your data and querying it.
@@ -17,10 +17,10 @@ We've chosen [Astra DB](https://astra.datastax.com/signup?utm_source=langflow-pr
## Prerequisites
- Langflow v1.0 alpha is also available in [HuggingFace Spaces](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true). Try it out or follow the instructions [here](../getting-started/huggingface-spaces) to install it locally.
+ Langflow v1.0 alpha is also available in HuggingFace Spaces. [Clone the space using this link](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) to create your own Langflow workspace in minutes.
-* [Langflow installed](../getting-started/install-langflow.mdx)
+* [Langflow installed and running](../getting-started/install-langflow.mdx)
* [OpenAI API key](https://platform.openai.com)
diff --git a/docs/docs/tutorials/chatprompttemplate_guide.mdx b/docs/docs/tutorials/chatprompttemplate_guide.mdx
index 05a8f3333..48059b134 100644
--- a/docs/docs/tutorials/chatprompttemplate_guide.mdx
+++ b/docs/docs/tutorials/chatprompttemplate_guide.mdx
@@ -3,7 +3,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
-# Building chatbots with System Message
+# Building Chatbots with System Message
## Overview
diff --git a/docs/docs/tutorials/loading_document.mdx b/docs/docs/tutorials/loading_document.mdx
index 73fb85968..4a6143a0e 100644
--- a/docs/docs/tutorials/loading_document.mdx
+++ b/docs/docs/tutorials/loading_document.mdx
@@ -3,7 +3,7 @@ import useBaseUrl from "@docusaurus/useBaseUrl";
import ZoomableImage from "/src/theme/ZoomableImage.js";
import ReactPlayer from "react-player";
-# Integrating documents with prompt variables
+# Integrating Documents with Prompt Variables
## Overview
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 7a5d5bdc2..2b891b589 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -14,9 +14,7 @@ module.exports = {
"index",
"getting-started/install-langflow",
"getting-started/quickstart",
- "getting-started/huggingface-spaces",
"getting-started/canvas",
- "getting-started/flows-components-collections",
"migration/possible-installation-issues",
"getting-started/new-to-llms",
],
@@ -131,5 +129,28 @@ module.exports = {
"contributing/contribute-component",
],
},
+ {
+ type: "category",
+ label: "Integrations",
+ collapsed: false,
+ items: [
+ {
+ type: "category",
+ label: "Notion",
+ items: [
+ "integrations/notion/intro",
+ "integrations/notion/setup",
+ "integrations/notion/search",
+ "integrations/notion/list-database-properties",
+ "integrations/notion/list-pages",
+ "integrations/notion/list-users",
+ "integrations/notion/page-create",
+ "integrations/notion/add-content-to-page",
+ "integrations/notion/page-update",
+ "integrations/notion/page-content-viewer",
+ ],
+ },
+ ],
+ },
],
};
diff --git a/docs/static/data/AstraDB-RAG-Flows.json b/docs/static/data/AstraDB-RAG-Flows.json
index d38364b4a..10dafa85f 100644
--- a/docs/static/data/AstraDB-RAG-Flows.json
+++ b/docs/static/data/AstraDB-RAG-Flows.json
@@ -1,3147 +1,3403 @@
{
- "id": "51e2b78a-199b-4054-9f32-e288eef6924c",
- "data": {
- "nodes": [
- {
- "id": "ChatInput-yxMKE",
- "type": "genericNode",
- "position": {
- "x": 1195.5276981160775,
- "y": 209.421875
- },
- "data": {
- "type": "ChatInput",
- "node": {
- "template": {
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Message\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "input_value": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "input_value",
- "display_name": "Message",
- "advanced": false,
- "input_types": [],
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "value": "what is a line"
- },
- "return_record": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "return_record",
- "display_name": "Return Record",
- "advanced": true,
- "dynamic": false,
- "info": "Return the message as a record containing the sender, sender_name, and session_id.",
- "load_from_db": false,
- "title_case": false
- },
- "sender": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "User",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": ["Machine", "User"],
- "name": "sender",
- "display_name": "Sender Type",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "sender_name": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "User",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "sender_name",
- "display_name": "Sender Name",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "session_id": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "session_id",
- "display_name": "Session ID",
- "advanced": true,
- "dynamic": false,
- "info": "If provided, the message will be stored in the memory.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "_type": "CustomComponent"
- },
- "description": "Get chat inputs from the Playground.",
- "icon": "ChatInput",
- "base_classes": ["Text", "str", "object", "Record"],
- "display_name": "Chat Input",
- "documentation": "",
- "custom_fields": {
- "sender": null,
- "sender_name": null,
- "input_value": null,
- "session_id": null,
- "return_record": null
- },
- "output_types": ["Text", "Record"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "ChatInput-yxMKE"
- },
- "selected": false,
- "width": 384,
- "height": 383
- },
- {
- "id": "TextOutput-BDknO",
- "type": "genericNode",
- "position": {
- "x": 2322.600672827879,
- "y": 604.9467307442569
- },
- "data": {
- "type": "TextOutput",
- "node": {
- "template": {
- "input_value": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "input_value",
- "display_name": "Value",
- "advanced": false,
- "input_types": ["Record", "Text"],
- "dynamic": false,
- "info": "Text or Record to be passed as output.",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextOutput(TextComponent):\n display_name = \"Text Output\"\n description = \"Display a text output in the Playground.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as output.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(self, input_value: Optional[Text] = \"\", record_template: str = \"\") -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "record_template": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "{text}",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "record_template",
- "display_name": "Record Template",
- "advanced": true,
- "dynamic": false,
- "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "_type": "CustomComponent"
- },
- "description": "Display a text output in the Playground.",
- "icon": "type",
- "base_classes": ["object", "Text", "str"],
- "display_name": "Extracted Chunks",
- "documentation": "",
- "custom_fields": {
- "input_value": null,
- "record_template": null
- },
- "output_types": ["Text"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "TextOutput-BDknO"
- },
- "selected": false,
- "width": 384,
- "height": 289,
- "positionAbsolute": {
- "x": 2322.600672827879,
- "y": 604.9467307442569
- },
- "dragging": false
- },
- {
- "id": "OpenAIEmbeddings-ZlOk1",
- "type": "genericNode",
- "position": {
- "x": 1183.667250865064,
- "y": 687.3171828430261
- },
- "data": {
- "type": "OpenAIEmbeddings",
- "node": {
- "template": {
- "allowed_special": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": [],
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "allowed_special",
- "display_name": "Allowed Special",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "chunk_size": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 1000,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "chunk_size",
- "display_name": "Chunk Size",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "client": {
- "type": "Any",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "client",
- "display_name": "Client",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "default_headers": {
- "type": "dict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "default_headers",
- "display_name": "Default Headers",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "default_query": {
- "type": "NestedDict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": {},
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "default_query",
- "display_name": "Default Query",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "deployment": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "text-embedding-ada-002",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "deployment",
- "display_name": "Deployment",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "disallowed_special": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": ["all"],
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "disallowed_special",
- "display_name": "Disallowed Special",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "embedding_ctx_length": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 8191,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "embedding_ctx_length",
- "display_name": "Embedding Context Length",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "max_retries": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 6,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "max_retries",
- "display_name": "Max Retries",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "model": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "text-embedding-ada-002",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": [
- "text-embedding-3-small",
- "text-embedding-3-large",
- "text-embedding-ada-002"
- ],
- "name": "model",
- "display_name": "Model",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "model_kwargs": {
- "type": "NestedDict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": {},
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "model_kwargs",
- "display_name": "Model Kwargs",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "openai_api_base": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_base",
- "display_name": "OpenAI API Base",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_key": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_key",
- "display_name": "OpenAI API Key",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"],
- "value": ""
- },
- "openai_api_type": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_type",
- "display_name": "OpenAI API Type",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_version": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_api_version",
- "display_name": "OpenAI API Version",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_organization": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_organization",
- "display_name": "OpenAI Organization",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_proxy": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_proxy",
- "display_name": "OpenAI Proxy",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "request_timeout": {
- "type": "float",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "request_timeout",
- "display_name": "Request Timeout",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "rangeSpec": {
- "step_type": "float",
- "min": -1,
- "max": 1,
- "step": 0.1
+ "id": "51e2b78a-199b-4054-9f32-e288eef6924c",
+ "data": {
+ "nodes": [
+ {
+ "id": "ChatInput-yxMKE",
+ "type": "genericNode",
+ "position": {
+ "x": 1195.5276981160775,
+ "y": 209.421875
},
- "load_from_db": false,
- "title_case": false
- },
- "show_progress_bar": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "show_progress_bar",
- "display_name": "Show Progress Bar",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "skip_empty": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "skip_empty",
- "display_name": "Skip Empty",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "tiktoken_enable": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": true,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "tiktoken_enable",
- "display_name": "TikToken Enable",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "tiktoken_model_name": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "tiktoken_model_name",
- "display_name": "TikToken Model Name",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "_type": "CustomComponent"
- },
- "description": "Generate embeddings using OpenAI models.",
- "base_classes": ["Embeddings"],
- "display_name": "OpenAI Embeddings",
- "documentation": "",
- "custom_fields": {
- "openai_api_key": null,
- "default_headers": null,
- "default_query": null,
- "allowed_special": null,
- "disallowed_special": null,
- "chunk_size": null,
- "client": null,
- "deployment": null,
- "embedding_ctx_length": null,
- "max_retries": null,
- "model": null,
- "model_kwargs": null,
- "openai_api_base": null,
- "openai_api_type": null,
- "openai_api_version": null,
- "openai_organization": null,
- "openai_proxy": null,
- "request_timeout": null,
- "show_progress_bar": null,
- "skip_empty": null,
- "tiktoken_enable": null,
- "tiktoken_model_name": null
- },
- "output_types": ["Embeddings"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "OpenAIEmbeddings-ZlOk1"
- },
- "selected": false,
- "width": 384,
- "height": 383,
- "dragging": false
- },
- {
- "id": "OpenAIModel-EjXlN",
- "type": "genericNode",
- "position": {
- "x": 3410.117202077183,
- "y": 431.2038048137648
- },
- "data": {
- "type": "OpenAIModel",
- "node": {
- "template": {
- "input_value": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "input_value",
- "display_name": "Input",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\"},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": [\n \"gpt-4-turbo-preview\",\n \"gpt-3.5-turbo\",\n \"gpt-4-0125-preview\",\n \"gpt-4-1106-preview\",\n \"gpt-4-vision-preview\",\n \"gpt-3.5-turbo-0125\",\n \"gpt-3.5-turbo-1106\",\n ],\n \"value\": \"gpt-4-turbo-preview\",\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float,\n model_name: str,\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n output = ChatOpenAI(\n max_tokens=max_tokens,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=openai_api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "max_tokens": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 256,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "max_tokens",
- "display_name": "Max Tokens",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "model_kwargs": {
- "type": "NestedDict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": {},
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "model_kwargs",
- "display_name": "Model Kwargs",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "model_name": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "gpt-3.5-turbo",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": [
- "gpt-4-turbo-preview",
- "gpt-3.5-turbo",
- "gpt-4-0125-preview",
- "gpt-4-1106-preview",
- "gpt-4-vision-preview",
- "gpt-3.5-turbo-0125",
- "gpt-3.5-turbo-1106"
- ],
- "name": "model_name",
- "display_name": "Model Name",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_base": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_api_base",
- "display_name": "OpenAI API Base",
- "advanced": true,
- "dynamic": false,
- "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_key": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_key",
- "display_name": "OpenAI API Key",
- "advanced": false,
- "dynamic": false,
- "info": "The OpenAI API Key to use for the OpenAI model.",
- "load_from_db": true,
- "title_case": false,
- "input_types": ["Text"],
- "value": "OPENAI_API_KEY"
- },
- "stream": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "stream",
- "display_name": "Stream",
- "advanced": true,
- "dynamic": false,
- "info": "Stream the response from the model. Streaming works only in Chat.",
- "load_from_db": false,
- "title_case": false
- },
- "system_message": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "system_message",
- "display_name": "System Message",
- "advanced": true,
- "dynamic": false,
- "info": "System message to pass to the model.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "temperature": {
- "type": "float",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 0.1,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "temperature",
- "display_name": "Temperature",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "rangeSpec": {
- "step_type": "float",
- "min": -1,
- "max": 1,
- "step": 0.1
+ "data": {
+ "type": "ChatInput",
+ "node": {
+ "template": {
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Message\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "input_value": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "input_value",
+ "display_name": "Message",
+ "advanced": false,
+ "input_types": [],
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "value": "what is a line"
+ },
+ "return_record": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "return_record",
+ "display_name": "Return Record",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Return the message as a record containing the sender, sender_name, and session_id.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "sender": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "User",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "Machine",
+ "User"
+ ],
+ "name": "sender",
+ "display_name": "Sender Type",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "sender_name": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "User",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "sender_name",
+ "display_name": "Sender Name",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "session_id": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "session_id",
+ "display_name": "Session ID",
+ "advanced": true,
+ "dynamic": false,
+ "info": "If provided, the message will be stored in the memory.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Get chat inputs from the Playground.",
+ "icon": "ChatInput",
+ "base_classes": [
+ "Text",
+ "str",
+ "object",
+ "Record"
+ ],
+ "display_name": "Chat Input",
+ "documentation": "",
+ "custom_fields": {
+ "sender": null,
+ "sender_name": null,
+ "input_value": null,
+ "session_id": null,
+ "return_record": null
+ },
+ "output_types": [
+ "Text",
+ "Record"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "ChatInput-yxMKE"
},
- "load_from_db": false,
- "title_case": false
- },
- "_type": "CustomComponent"
+ "selected": false,
+ "width": 384,
+ "height": 383
},
- "description": "Generates text using OpenAI LLMs.",
- "icon": "OpenAI",
- "base_classes": ["object", "Text", "str"],
- "display_name": "OpenAI",
- "documentation": "",
- "custom_fields": {
- "input_value": null,
- "openai_api_key": null,
- "temperature": null,
- "model_name": null,
- "max_tokens": null,
- "model_kwargs": null,
- "openai_api_base": null,
- "stream": null,
- "system_message": null
+ {
+ "id": "TextOutput-BDknO",
+ "type": "genericNode",
+ "position": {
+ "x": 2322.600672827879,
+ "y": 604.9467307442569
+ },
+ "data": {
+ "type": "TextOutput",
+ "node": {
+ "template": {
+ "input_value": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "input_value",
+ "display_name": "Value",
+ "advanced": false,
+ "input_types": [
+ "Record",
+ "Text"
+ ],
+ "dynamic": false,
+ "info": "Text or Record to be passed as output.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextOutput(TextComponent):\n display_name = \"Text Output\"\n description = \"Display a text output in the Playground.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Value\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as output.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(self, input_value: Optional[Text] = \"\", record_template: str = \"\") -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "record_template": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "{text}",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "record_template",
+ "display_name": "Record Template",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Display a text output in the Playground.",
+ "icon": "type",
+ "base_classes": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "display_name": "Extracted Chunks",
+ "documentation": "",
+ "custom_fields": {
+ "input_value": null,
+ "record_template": null
+ },
+ "output_types": [
+ "Text"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "TextOutput-BDknO"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 289,
+ "positionAbsolute": {
+ "x": 2322.600672827879,
+ "y": 604.9467307442569
+ },
+ "dragging": false
},
- "output_types": ["Text"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [
- "max_tokens",
- "model_kwargs",
- "model_name",
- "openai_api_base",
- "openai_api_key",
- "temperature",
- "input_value",
- "system_message",
- "stream"
- ],
- "beta": false
- },
- "id": "OpenAIModel-EjXlN"
- },
- "selected": true,
- "width": 384,
- "height": 563,
- "positionAbsolute": {
- "x": 3410.117202077183,
- "y": 431.2038048137648
- },
- "dragging": false
- },
- {
- "id": "Prompt-xeI6K",
- "type": "genericNode",
- "position": {
- "x": 2969.0261961391298,
- "y": 442.1613649809069
- },
- "data": {
- "type": "Prompt",
- "node": {
- "template": {
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "template": {
- "type": "prompt",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: ",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "template",
- "display_name": "Template",
- "advanced": false,
- "input_types": ["Text"],
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "_type": "CustomComponent",
- "context": {
- "field_type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "context",
- "display_name": "context",
- "advanced": false,
- "input_types": [
- "Document",
- "BaseOutputParser",
- "Record",
- "Text"
- ],
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "type": "str"
- },
- "question": {
- "field_type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "question",
- "display_name": "question",
- "advanced": false,
- "input_types": [
- "Document",
- "BaseOutputParser",
- "Record",
- "Text"
- ],
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "type": "str"
- }
+ {
+ "id": "OpenAIEmbeddings-ZlOk1",
+ "type": "genericNode",
+ "position": {
+ "x": 1183.667250865064,
+ "y": 687.3171828430261
+ },
+ "data": {
+ "type": "OpenAIEmbeddings",
+ "node": {
+ "template": {
+ "allowed_special": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": [],
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "allowed_special",
+ "display_name": "Allowed Special",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "chunk_size": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 1000,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "chunk_size",
+ "display_name": "Chunk Size",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "client": {
+ "type": "Any",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "client",
+ "display_name": "Client",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "default_headers": {
+ "type": "dict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "default_headers",
+ "display_name": "Default Headers",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "default_query": {
+ "type": "NestedDict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": {},
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "default_query",
+ "display_name": "Default Query",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "deployment": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "text-embedding-ada-002",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "deployment",
+ "display_name": "Deployment",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "disallowed_special": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": [
+ "all"
+ ],
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "disallowed_special",
+ "display_name": "Disallowed Special",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "embedding_ctx_length": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 8191,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "embedding_ctx_length",
+ "display_name": "Embedding Context Length",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "max_retries": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 6,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "max_retries",
+ "display_name": "Max Retries",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "model": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "text-embedding-ada-002",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "text-embedding-3-small",
+ "text-embedding-3-large",
+ "text-embedding-ada-002"
+ ],
+ "name": "model",
+ "display_name": "Model",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "model_kwargs": {
+ "type": "NestedDict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": {},
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "model_kwargs",
+ "display_name": "Model Kwargs",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "openai_api_base": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_base",
+ "display_name": "OpenAI API Base",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_key": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_key",
+ "display_name": "OpenAI API Key",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "OPENAI_API_KEY"
+ },
+ "openai_api_type": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_type",
+ "display_name": "OpenAI API Type",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_version": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_api_version",
+ "display_name": "OpenAI API Version",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_organization": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_organization",
+ "display_name": "OpenAI Organization",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_proxy": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_proxy",
+ "display_name": "OpenAI Proxy",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "request_timeout": {
+ "type": "float",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "request_timeout",
+ "display_name": "Request Timeout",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "rangeSpec": {
+ "step_type": "float",
+ "min": -1,
+ "max": 1,
+ "step": 0.1
+ },
+ "load_from_db": false,
+ "title_case": false
+ },
+ "show_progress_bar": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "show_progress_bar",
+ "display_name": "Show Progress Bar",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "skip_empty": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "skip_empty",
+ "display_name": "Skip Empty",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "tiktoken_enable": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": true,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "tiktoken_enable",
+ "display_name": "TikToken Enable",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "tiktoken_model_name": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "tiktoken_model_name",
+ "display_name": "TikToken Model Name",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Generate embeddings using OpenAI models.",
+ "base_classes": [
+ "Embeddings"
+ ],
+ "display_name": "OpenAI Embeddings",
+ "documentation": "",
+ "custom_fields": {
+ "openai_api_key": null,
+ "default_headers": null,
+ "default_query": null,
+ "allowed_special": null,
+ "disallowed_special": null,
+ "chunk_size": null,
+ "client": null,
+ "deployment": null,
+ "embedding_ctx_length": null,
+ "max_retries": null,
+ "model": null,
+ "model_kwargs": null,
+ "openai_api_base": null,
+ "openai_api_type": null,
+ "openai_api_version": null,
+ "openai_organization": null,
+ "openai_proxy": null,
+ "request_timeout": null,
+ "show_progress_bar": null,
+ "skip_empty": null,
+ "tiktoken_enable": null,
+ "tiktoken_model_name": null
+ },
+ "output_types": [
+ "Embeddings"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "OpenAIEmbeddings-ZlOk1"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 383,
+ "dragging": false
},
- "description": "Create a prompt template with dynamic variables.",
- "icon": "prompts",
- "is_input": null,
- "is_output": null,
- "is_composition": null,
- "base_classes": ["object", "Text", "str"],
- "name": "",
- "display_name": "Prompt",
- "documentation": "",
- "custom_fields": {
- "template": ["context", "question"]
+ {
+ "id": "OpenAIModel-EjXlN",
+ "type": "genericNode",
+ "position": {
+ "x": 3410.117202077183,
+ "y": 431.2038048137648
+ },
+ "data": {
+ "type": "OpenAIModel",
+ "node": {
+ "template": {
+ "input_value": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "input_value",
+ "display_name": "Input",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\"},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": [\n \"gpt-4-turbo-preview\",\n \"gpt-3.5-turbo\",\n \"gpt-4-0125-preview\",\n \"gpt-4-1106-preview\",\n \"gpt-4-vision-preview\",\n \"gpt-3.5-turbo-0125\",\n \"gpt-3.5-turbo-1106\",\n ],\n \"value\": \"gpt-4-turbo-preview\",\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float,\n model_name: str,\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n output = ChatOpenAI(\n max_tokens=max_tokens,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=openai_api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "max_tokens": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 256,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "max_tokens",
+ "display_name": "Max Tokens",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "model_kwargs": {
+ "type": "NestedDict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": {},
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "model_kwargs",
+ "display_name": "Model Kwargs",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "model_name": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "gpt-3.5-turbo",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "gpt-4-turbo-preview",
+ "gpt-3.5-turbo",
+ "gpt-4-0125-preview",
+ "gpt-4-1106-preview",
+ "gpt-4-vision-preview",
+ "gpt-3.5-turbo-0125",
+ "gpt-3.5-turbo-1106"
+ ],
+ "name": "model_name",
+ "display_name": "Model Name",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_base": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_api_base",
+ "display_name": "OpenAI API Base",
+ "advanced": true,
+ "dynamic": false,
+ "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_key": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_key",
+ "display_name": "OpenAI API Key",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The OpenAI API Key to use for the OpenAI model.",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "OPENAI_API_KEY"
+ },
+ "stream": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "stream",
+ "display_name": "Stream",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Stream the response from the model. Streaming works only in Chat.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "system_message": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "system_message",
+ "display_name": "System Message",
+ "advanced": true,
+ "dynamic": false,
+ "info": "System message to pass to the model.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "temperature": {
+ "type": "float",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 0.1,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "temperature",
+ "display_name": "Temperature",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "rangeSpec": {
+ "step_type": "float",
+ "min": -1,
+ "max": 1,
+ "step": 0.1
+ },
+ "load_from_db": false,
+ "title_case": false
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Generates text using OpenAI LLMs.",
+ "icon": "OpenAI",
+ "base_classes": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "display_name": "OpenAI",
+ "documentation": "",
+ "custom_fields": {
+ "input_value": null,
+ "openai_api_key": null,
+ "temperature": null,
+ "model_name": null,
+ "max_tokens": null,
+ "model_kwargs": null,
+ "openai_api_base": null,
+ "stream": null,
+ "system_message": null
+ },
+ "output_types": [
+ "Text"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [
+ "max_tokens",
+ "model_kwargs",
+ "model_name",
+ "openai_api_base",
+ "openai_api_key",
+ "temperature",
+ "input_value",
+ "system_message",
+ "stream"
+ ],
+ "beta": false
+ },
+ "id": "OpenAIModel-EjXlN"
+ },
+ "selected": true,
+ "width": 384,
+ "height": 563,
+ "positionAbsolute": {
+ "x": 3410.117202077183,
+ "y": 431.2038048137648
+ },
+ "dragging": false
},
- "output_types": ["Text"],
- "full_path": null,
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false,
- "error": null
- },
- "id": "Prompt-xeI6K",
- "description": "Create a prompt template with dynamic variables.",
- "display_name": "Prompt"
- },
- "selected": false,
- "width": 384,
- "height": 477,
- "positionAbsolute": {
- "x": 2969.0261961391298,
- "y": 442.1613649809069
- },
- "dragging": false
- },
- {
- "id": "ChatOutput-Q39I8",
- "type": "genericNode",
- "position": {
- "x": 3887.2073667611485,
- "y": 588.4801225794856
- },
- "data": {
- "type": "ChatOutput",
- "node": {
- "template": {
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n record_template: Optional[str] = \"{text}\",\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n record_template=record_template,\n )\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "input_value": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "input_value",
- "display_name": "Message",
- "advanced": false,
- "input_types": ["Text"],
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "record_template": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "{text}",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "record_template",
- "display_name": "Record Template",
- "advanced": true,
- "dynamic": false,
- "info": "In case of Message being a Record, this template will be used to convert it to text.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "return_record": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "return_record",
- "display_name": "Return Record",
- "advanced": true,
- "dynamic": false,
- "info": "Return the message as a record containing the sender, sender_name, and session_id.",
- "load_from_db": false,
- "title_case": false
- },
- "sender": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "Machine",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": ["Machine", "User"],
- "name": "sender",
- "display_name": "Sender Type",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "sender_name": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "AI",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "sender_name",
- "display_name": "Sender Name",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "session_id": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "session_id",
- "display_name": "Session ID",
- "advanced": true,
- "dynamic": false,
- "info": "If provided, the message will be stored in the memory.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "_type": "CustomComponent"
+ {
+ "id": "Prompt-xeI6K",
+ "type": "genericNode",
+ "position": {
+ "x": 2969.0261961391298,
+ "y": 442.1613649809069
+ },
+ "data": {
+ "type": "Prompt",
+ "node": {
+ "template": {
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from langchain_core.prompts import PromptTemplate\n\nfrom langflow.field_typing import Prompt, TemplateField, Text\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Text:\n from langflow.base.prompts.utils import dict_values_to_string\n\n prompt_template = PromptTemplate.from_template(Text(template))\n kwargs = dict_values_to_string(kwargs)\n kwargs = {k: \"\\n\".join(v) if isinstance(v, list) else v for k, v in kwargs.items()}\n try:\n formated_prompt = prompt_template.format(**kwargs)\n except Exception as exc:\n raise ValueError(f\"Error formatting prompt: {exc}\") from exc\n self.status = f'Prompt:\\n\"{formated_prompt}\"'\n return formated_prompt\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "template": {
+ "type": "prompt",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "{context}\n\n---\n\nGiven the context above, answer the question as best as possible.\n\nQuestion: {question}\n\nAnswer: ",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "template",
+ "display_name": "Template",
+ "advanced": false,
+ "input_types": [
+ "Text"
+ ],
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "_type": "CustomComponent",
+ "context": {
+ "field_type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "context",
+ "display_name": "context",
+ "advanced": false,
+ "input_types": [
+ "Document",
+ "BaseOutputParser",
+ "Record",
+ "Text"
+ ],
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "type": "str"
+ },
+ "question": {
+ "field_type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "question",
+ "display_name": "question",
+ "advanced": false,
+ "input_types": [
+ "Document",
+ "BaseOutputParser",
+ "Record",
+ "Text"
+ ],
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "type": "str"
+ }
+ },
+ "description": "Create a prompt template with dynamic variables.",
+ "icon": "prompts",
+ "is_input": null,
+ "is_output": null,
+ "is_composition": null,
+ "base_classes": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "name": "",
+ "display_name": "Prompt",
+ "documentation": "",
+ "custom_fields": {
+ "template": [
+ "context",
+ "question"
+ ]
+ },
+ "output_types": [
+ "Text"
+ ],
+ "full_path": null,
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false,
+ "error": null
+ },
+ "id": "Prompt-xeI6K",
+ "description": "Create a prompt template with dynamic variables.",
+ "display_name": "Prompt"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 477,
+ "positionAbsolute": {
+ "x": 2969.0261961391298,
+ "y": 442.1613649809069
+ },
+ "dragging": false
},
- "description": "Display a chat message in the Playground.",
- "icon": "ChatOutput",
- "base_classes": ["object", "Text", "Record", "str"],
- "display_name": "Chat Output",
- "documentation": "",
- "custom_fields": {
- "sender": null,
- "sender_name": null,
- "input_value": null,
- "session_id": null,
- "return_record": null,
- "record_template": null
+ {
+ "id": "ChatOutput-Q39I8",
+ "type": "genericNode",
+ "position": {
+ "x": 3887.2073667611485,
+ "y": 588.4801225794856
+ },
+ "data": {
+ "type": "ChatOutput",
+ "node": {
+ "template": {
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n record_template: Optional[str] = \"{text}\",\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n record_template=record_template,\n )\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "input_value": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "input_value",
+ "display_name": "Message",
+ "advanced": false,
+ "input_types": [
+ "Text"
+ ],
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "record_template": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "{text}",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "record_template",
+ "display_name": "Record Template",
+ "advanced": true,
+ "dynamic": false,
+ "info": "In case of Message being a Record, this template will be used to convert it to text.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "return_record": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "return_record",
+ "display_name": "Return Record",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Return the message as a record containing the sender, sender_name, and session_id.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "sender": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "Machine",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "Machine",
+ "User"
+ ],
+ "name": "sender",
+ "display_name": "Sender Type",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "sender_name": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "AI",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "sender_name",
+ "display_name": "Sender Name",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "session_id": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "session_id",
+ "display_name": "Session ID",
+ "advanced": true,
+ "dynamic": false,
+ "info": "If provided, the message will be stored in the memory.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Display a chat message in the Playground.",
+ "icon": "ChatOutput",
+ "base_classes": [
+ "object",
+ "Text",
+ "Record",
+ "str"
+ ],
+ "display_name": "Chat Output",
+ "documentation": "",
+ "custom_fields": {
+ "sender": null,
+ "sender_name": null,
+ "input_value": null,
+ "session_id": null,
+ "return_record": null,
+ "record_template": null
+ },
+ "output_types": [
+ "Text",
+ "Record"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "ChatOutput-Q39I8"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 383,
+ "positionAbsolute": {
+ "x": 3887.2073667611485,
+ "y": 588.4801225794856
+ },
+ "dragging": false
},
- "output_types": ["Text", "Record"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "ChatOutput-Q39I8"
- },
- "selected": false,
- "width": 384,
- "height": 383,
- "positionAbsolute": {
- "x": 3887.2073667611485,
- "y": 588.4801225794856
- },
- "dragging": false
- },
- {
- "id": "File-t0a6a",
- "type": "genericNode",
- "position": {
- "x": 2257.233450682836,
- "y": 1747.5389618367233
- },
- "data": {
- "type": "File",
- "node": {
- "template": {
- "path": {
- "type": "file",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [
- ".txt",
- ".md",
- ".mdx",
- ".csv",
- ".json",
- ".yaml",
- ".yml",
- ".xml",
- ".html",
- ".htm",
- ".pdf",
- ".docx"
- ],
- "file_path": "51e2b78a-199b-4054-9f32-e288eef6924c/Langflow conversation.pdf",
- "password": false,
- "name": "path",
- "display_name": "Path",
- "advanced": false,
- "dynamic": false,
- "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx",
- "load_from_db": false,
- "title_case": false,
- "value": ""
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from pathlib import Path\nfrom typing import Any, Dict\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\n\n\nclass FileComponent(CustomComponent):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"path\": {\n \"display_name\": \"Path\",\n \"field_type\": \"file\",\n \"file_types\": TEXT_FILE_TYPES,\n \"info\": f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n },\n \"silent_errors\": {\n \"display_name\": \"Silent Errors\",\n \"advanced\": True,\n \"info\": \"If true, errors will not raise an exception.\",\n },\n }\n\n def load_file(self, path: str, silent_errors: bool = False) -> Record:\n resolved_path = self.resolve_path(path)\n path_obj = Path(resolved_path)\n extension = path_obj.suffix[1:].lower()\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n record = parse_text_file_to_record(resolved_path, silent_errors)\n self.status = record if record else \"No data\"\n return record or Record()\n\n def build(\n self,\n path: str,\n silent_errors: bool = False,\n ) -> Record:\n record = self.load_file(path, silent_errors)\n self.status = record\n return record\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "silent_errors": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "silent_errors",
- "display_name": "Silent Errors",
- "advanced": true,
- "dynamic": false,
- "info": "If true, errors will not raise an exception.",
- "load_from_db": false,
- "title_case": false
- },
- "_type": "CustomComponent"
+ {
+ "id": "File-t0a6a",
+ "type": "genericNode",
+ "position": {
+ "x": 2257.233450682836,
+ "y": 1747.5389618367233
+ },
+ "data": {
+ "type": "File",
+ "node": {
+ "template": {
+ "path": {
+ "type": "file",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [
+ ".txt",
+ ".md",
+ ".mdx",
+ ".csv",
+ ".json",
+ ".yaml",
+ ".yml",
+ ".xml",
+ ".html",
+ ".htm",
+ ".pdf",
+ ".docx"
+ ],
+ "file_path": "51e2b78a-199b-4054-9f32-e288eef6924c/Langflow conversation.pdf",
+ "password": false,
+ "name": "path",
+ "display_name": "Path",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Supported file types: txt, md, mdx, csv, json, yaml, yml, xml, html, htm, pdf, docx",
+ "load_from_db": false,
+ "title_case": false,
+ "value": ""
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from pathlib import Path\nfrom typing import Any, Dict\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\n\n\nclass FileComponent(CustomComponent):\n display_name = \"File\"\n description = \"A generic file loader.\"\n icon = \"file-text\"\n\n def build_config(self) -> Dict[str, Any]:\n return {\n \"path\": {\n \"display_name\": \"Path\",\n \"field_type\": \"file\",\n \"file_types\": TEXT_FILE_TYPES,\n \"info\": f\"Supported file types: {', '.join(TEXT_FILE_TYPES)}\",\n },\n \"silent_errors\": {\n \"display_name\": \"Silent Errors\",\n \"advanced\": True,\n \"info\": \"If true, errors will not raise an exception.\",\n },\n }\n\n def load_file(self, path: str, silent_errors: bool = False) -> Record:\n resolved_path = self.resolve_path(path)\n path_obj = Path(resolved_path)\n extension = path_obj.suffix[1:].lower()\n if extension == \"doc\":\n raise ValueError(\"doc files are not supported. Please save as .docx\")\n if extension not in TEXT_FILE_TYPES:\n raise ValueError(f\"Unsupported file type: {extension}\")\n record = parse_text_file_to_record(resolved_path, silent_errors)\n self.status = record if record else \"No data\"\n return record or Record()\n\n def build(\n self,\n path: str,\n silent_errors: bool = False,\n ) -> Record:\n record = self.load_file(path, silent_errors)\n self.status = record\n return record\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "silent_errors": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "silent_errors",
+ "display_name": "Silent Errors",
+ "advanced": true,
+ "dynamic": false,
+ "info": "If true, errors will not raise an exception.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "A generic file loader.",
+ "icon": "file-text",
+ "base_classes": [
+ "Record"
+ ],
+ "display_name": "File",
+ "documentation": "",
+ "custom_fields": {
+ "path": null,
+ "silent_errors": null
+ },
+ "output_types": [
+ "Record"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "File-t0a6a"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 281,
+ "positionAbsolute": {
+ "x": 2257.233450682836,
+ "y": 1747.5389618367233
+ },
+ "dragging": false
},
- "description": "A generic file loader.",
- "icon": "file-text",
- "base_classes": ["Record"],
- "display_name": "File",
- "documentation": "",
- "custom_fields": {
- "path": null,
- "silent_errors": null
+ {
+ "id": "RecursiveCharacterTextSplitter-tR9QM",
+ "type": "genericNode",
+ "position": {
+ "x": 2791.013514133929,
+ "y": 1462.9588953494142
+ },
+ "data": {
+ "type": "RecursiveCharacterTextSplitter",
+ "node": {
+ "template": {
+ "inputs": {
+ "type": "Document",
+ "required": true,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "inputs",
+ "display_name": "Input",
+ "advanced": false,
+ "input_types": [
+ "Document",
+ "Record"
+ ],
+ "dynamic": false,
+ "info": "The texts to split.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "chunk_overlap": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 200,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "chunk_overlap",
+ "display_name": "Chunk Overlap",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The amount of overlap between chunks.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "chunk_size": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 1000,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "chunk_size",
+ "display_name": "Chunk Size",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The maximum length of each chunk.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Optional\n\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain_core.documents import Document\n\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\nfrom langflow.utils.util import build_loader_repr_from_records, unescape_string\n\n\nclass RecursiveCharacterTextSplitterComponent(CustomComponent):\n display_name: str = \"Recursive Character Text Splitter\"\n description: str = \"Split text into chunks of a specified length.\"\n documentation: str = \"https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter\"\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Input\",\n \"info\": \"The texts to split.\",\n \"input_types\": [\"Document\", \"Record\"],\n },\n \"separators\": {\n \"display_name\": \"Separators\",\n \"info\": 'The characters to split on.\\nIf left empty defaults to [\"\\\\n\\\\n\", \"\\\\n\", \" \", \"\"].',\n \"is_list\": True,\n },\n \"chunk_size\": {\n \"display_name\": \"Chunk Size\",\n \"info\": \"The maximum length of each chunk.\",\n \"field_type\": \"int\",\n \"value\": 1000,\n },\n \"chunk_overlap\": {\n \"display_name\": \"Chunk Overlap\",\n \"info\": \"The amount of overlap between chunks.\",\n \"field_type\": \"int\",\n \"value\": 200,\n },\n \"code\": {\"show\": False},\n }\n\n def build(\n self,\n inputs: list[Document],\n separators: Optional[list[str]] = None,\n chunk_size: Optional[int] = 1000,\n chunk_overlap: Optional[int] = 200,\n ) -> list[Record]:\n \"\"\"\n Split text into chunks of a specified length.\n\n Args:\n separators (list[str]): The characters to split on.\n chunk_size (int): The maximum length of each chunk.\n chunk_overlap (int): The amount of overlap between chunks.\n length_function (function): The function to use to calculate the length of the text.\n\n Returns:\n list[str]: The chunks of text.\n \"\"\"\n\n if separators == \"\":\n separators = None\n elif separators:\n # check if the separators list has escaped characters\n # if there are escaped characters, unescape them\n separators = [unescape_string(x) for x in separators]\n\n # Make sure chunk_size and chunk_overlap are ints\n if isinstance(chunk_size, str):\n chunk_size = int(chunk_size)\n if isinstance(chunk_overlap, str):\n chunk_overlap = int(chunk_overlap)\n splitter = RecursiveCharacterTextSplitter(\n separators=separators,\n chunk_size=chunk_size,\n chunk_overlap=chunk_overlap,\n )\n documents = []\n for _input in inputs:\n if isinstance(_input, Record):\n documents.append(_input.to_lc_document())\n else:\n documents.append(_input)\n docs = splitter.split_documents(documents)\n records = self.to_records(docs)\n self.repr_value = build_loader_repr_from_records(records)\n return records\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "separators": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "separators",
+ "display_name": "Separators",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The characters to split on.\nIf left empty defaults to [\"\\n\\n\", \"\\n\", \" \", \"\"].",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": [
+ ""
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Split text into chunks of a specified length.",
+ "base_classes": [
+ "Record"
+ ],
+ "display_name": "Recursive Character Text Splitter",
+ "documentation": "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter",
+ "custom_fields": {
+ "inputs": null,
+ "separators": null,
+ "chunk_size": null,
+ "chunk_overlap": null
+ },
+ "output_types": [
+ "Record"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "RecursiveCharacterTextSplitter-tR9QM"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 501,
+ "positionAbsolute": {
+ "x": 2791.013514133929,
+ "y": 1462.9588953494142
+ },
+ "dragging": false
},
- "output_types": ["Record"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "File-t0a6a"
- },
- "selected": false,
- "width": 384,
- "height": 281,
- "positionAbsolute": {
- "x": 2257.233450682836,
- "y": 1747.5389618367233
- },
- "dragging": false
- },
- {
- "id": "RecursiveCharacterTextSplitter-tR9QM",
- "type": "genericNode",
- "position": {
- "x": 2791.013514133929,
- "y": 1462.9588953494142
- },
- "data": {
- "type": "RecursiveCharacterTextSplitter",
- "node": {
- "template": {
- "inputs": {
- "type": "Document",
- "required": true,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "inputs",
- "display_name": "Input",
- "advanced": false,
- "input_types": ["Document", "Record"],
- "dynamic": false,
- "info": "The texts to split.",
- "load_from_db": false,
- "title_case": false
- },
- "chunk_overlap": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 200,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "chunk_overlap",
- "display_name": "Chunk Overlap",
- "advanced": false,
- "dynamic": false,
- "info": "The amount of overlap between chunks.",
- "load_from_db": false,
- "title_case": false
- },
- "chunk_size": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 1000,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "chunk_size",
- "display_name": "Chunk Size",
- "advanced": false,
- "dynamic": false,
- "info": "The maximum length of each chunk.",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Optional\n\nfrom langchain.text_splitter import RecursiveCharacterTextSplitter\nfrom langchain_core.documents import Document\n\nfrom langflow.interface.custom.custom_component import CustomComponent\nfrom langflow.schema import Record\nfrom langflow.utils.util import build_loader_repr_from_records, unescape_string\n\n\nclass RecursiveCharacterTextSplitterComponent(CustomComponent):\n display_name: str = \"Recursive Character Text Splitter\"\n description: str = \"Split text into chunks of a specified length.\"\n documentation: str = \"https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter\"\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Input\",\n \"info\": \"The texts to split.\",\n \"input_types\": [\"Document\", \"Record\"],\n },\n \"separators\": {\n \"display_name\": \"Separators\",\n \"info\": 'The characters to split on.\\nIf left empty defaults to [\"\\\\n\\\\n\", \"\\\\n\", \" \", \"\"].',\n \"is_list\": True,\n },\n \"chunk_size\": {\n \"display_name\": \"Chunk Size\",\n \"info\": \"The maximum length of each chunk.\",\n \"field_type\": \"int\",\n \"value\": 1000,\n },\n \"chunk_overlap\": {\n \"display_name\": \"Chunk Overlap\",\n \"info\": \"The amount of overlap between chunks.\",\n \"field_type\": \"int\",\n \"value\": 200,\n },\n \"code\": {\"show\": False},\n }\n\n def build(\n self,\n inputs: list[Document],\n separators: Optional[list[str]] = None,\n chunk_size: Optional[int] = 1000,\n chunk_overlap: Optional[int] = 200,\n ) -> list[Record]:\n \"\"\"\n Split text into chunks of a specified length.\n\n Args:\n separators (list[str]): The characters to split on.\n chunk_size (int): The maximum length of each chunk.\n chunk_overlap (int): The amount of overlap between chunks.\n length_function (function): The function to use to calculate the length of the text.\n\n Returns:\n list[str]: The chunks of text.\n \"\"\"\n\n if separators == \"\":\n separators = None\n elif separators:\n # check if the separators list has escaped characters\n # if there are escaped characters, unescape them\n separators = [unescape_string(x) for x in separators]\n\n # Make sure chunk_size and chunk_overlap are ints\n if isinstance(chunk_size, str):\n chunk_size = int(chunk_size)\n if isinstance(chunk_overlap, str):\n chunk_overlap = int(chunk_overlap)\n splitter = RecursiveCharacterTextSplitter(\n separators=separators,\n chunk_size=chunk_size,\n chunk_overlap=chunk_overlap,\n )\n documents = []\n for _input in inputs:\n if isinstance(_input, Record):\n documents.append(_input.to_lc_document())\n else:\n documents.append(_input)\n docs = splitter.split_documents(documents)\n records = self.to_records(docs)\n self.repr_value = build_loader_repr_from_records(records)\n return records\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "separators": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "separators",
- "display_name": "Separators",
- "advanced": false,
- "dynamic": false,
- "info": "The characters to split on.\nIf left empty defaults to [\"\\n\\n\", \"\\n\", \" \", \"\"].",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"],
- "value": [""]
- },
- "_type": "CustomComponent"
+ {
+ "id": "AstraDBSearch-41nRz",
+ "type": "genericNode",
+ "position": {
+ "x": 1723.976434815103,
+ "y": 277.03317407245913
+ },
+ "data": {
+ "type": "AstraDBSearch",
+ "node": {
+ "template": {
+ "embedding": {
+ "type": "Embeddings",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "embedding",
+ "display_name": "Embedding",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Embedding to use",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "input_value": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "input_value",
+ "display_name": "Input Value",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Input value to search",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "api_endpoint": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "api_endpoint",
+ "display_name": "API Endpoint",
+ "advanced": false,
+ "dynamic": false,
+ "info": "API endpoint URL for the Astra DB service.",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "ASTRA_DB_API_ENDPOINT"
+ },
+ "batch_size": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "batch_size",
+ "display_name": "Batch Size",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional number of records to process in a single batch.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_delete_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_delete_concurrency",
+ "display_name": "Bulk Delete Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk delete operations.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_insert_batch_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_insert_batch_concurrency",
+ "display_name": "Bulk Insert Batch Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk insert operations.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_insert_overwrite_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_insert_overwrite_concurrency",
+ "display_name": "Bulk Insert Overwrite Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"Astra DB Search\"\n description = \"Searches an existing Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "collection_indexing_policy": {
+ "type": "dict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "collection_indexing_policy",
+ "display_name": "Collection Indexing Policy",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional dictionary defining the indexing policy for the collection.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "collection_name": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "collection_name",
+ "display_name": "Collection Name",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The name of the collection within Astra DB where the vectors will be stored.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "langflow"
+ },
+ "metadata_indexing_exclude": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metadata_indexing_exclude",
+ "display_name": "Metadata Indexing Exclude",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional list of metadata fields to exclude from the indexing.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "metadata_indexing_include": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metadata_indexing_include",
+ "display_name": "Metadata Indexing Include",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional list of metadata fields to include in the indexing.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "metric": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metric",
+ "display_name": "Metric",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional distance metric for vector comparisons in the vector store.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "namespace": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "namespace",
+ "display_name": "Namespace",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional namespace within Astra DB to use for the collection.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "number_of_results": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 4,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "number_of_results",
+ "display_name": "Number of Results",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Number of results to return.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "pre_delete_collection": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "pre_delete_collection",
+ "display_name": "Pre Delete Collection",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "search_type": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "Similarity",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "Similarity",
+ "MMR"
+ ],
+ "name": "search_type",
+ "display_name": "Search Type",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "setup_mode": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "Sync",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "Sync",
+ "Async",
+ "Off"
+ ],
+ "name": "setup_mode",
+ "display_name": "Setup Mode",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "token": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "token",
+ "display_name": "Token",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Authentication token for accessing Astra DB.",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "ASTRA_DB_APPLICATION_TOKEN"
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Searches an existing Astra DB Vector Store.",
+ "icon": "AstraDB",
+ "base_classes": [
+ "Record"
+ ],
+ "display_name": "Astra DB Search",
+ "documentation": "",
+ "custom_fields": {
+ "embedding": null,
+ "collection_name": null,
+ "input_value": null,
+ "token": null,
+ "api_endpoint": null,
+ "search_type": null,
+ "number_of_results": null,
+ "namespace": null,
+ "metric": null,
+ "batch_size": null,
+ "bulk_insert_batch_concurrency": null,
+ "bulk_insert_overwrite_concurrency": null,
+ "bulk_delete_concurrency": null,
+ "setup_mode": null,
+ "pre_delete_collection": null,
+ "metadata_indexing_include": null,
+ "metadata_indexing_exclude": null,
+ "collection_indexing_policy": null
+ },
+ "output_types": [
+ "Record"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [
+ "token",
+ "api_endpoint",
+ "collection_name",
+ "input_value",
+ "embedding"
+ ],
+ "beta": false
+ },
+ "id": "AstraDBSearch-41nRz"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 713,
+ "dragging": false,
+ "positionAbsolute": {
+ "x": 1723.976434815103,
+ "y": 277.03317407245913
+ }
},
- "description": "Split text into chunks of a specified length.",
- "base_classes": ["Record"],
- "display_name": "Recursive Character Text Splitter",
- "documentation": "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter",
- "custom_fields": {
- "inputs": null,
- "separators": null,
- "chunk_size": null,
- "chunk_overlap": null
+ {
+ "id": "AstraDB-eUCSS",
+ "type": "genericNode",
+ "position": {
+ "x": 3372.04958055989,
+ "y": 1611.0742035495277
+ },
+ "data": {
+ "type": "AstraDB",
+ "node": {
+ "template": {
+ "embedding": {
+ "type": "Embeddings",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "embedding",
+ "display_name": "Embedding",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Embedding to use",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "inputs": {
+ "type": "Record",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "inputs",
+ "display_name": "Inputs",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Optional list of records to be processed and stored in the vector store.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "api_endpoint": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "api_endpoint",
+ "display_name": "API Endpoint",
+ "advanced": false,
+ "dynamic": false,
+ "info": "API endpoint URL for the Astra DB service.",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "ASTRA_DB_API_ENDPOINT"
+ },
+ "batch_size": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "batch_size",
+ "display_name": "Batch Size",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional number of records to process in a single batch.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_delete_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_delete_concurrency",
+ "display_name": "Bulk Delete Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk delete operations.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_insert_batch_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_insert_batch_concurrency",
+ "display_name": "Bulk Insert Batch Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk insert operations.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "bulk_insert_overwrite_concurrency": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "bulk_insert_overwrite_concurrency",
+ "display_name": "Bulk Insert Overwrite Concurrency",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "collection_indexing_policy": {
+ "type": "dict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "collection_indexing_policy",
+ "display_name": "Collection Indexing Policy",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional dictionary defining the indexing policy for the collection.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "collection_name": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "collection_name",
+ "display_name": "Collection Name",
+ "advanced": false,
+ "dynamic": false,
+ "info": "The name of the collection within Astra DB where the vectors will be stored.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "langflow"
+ },
+ "metadata_indexing_exclude": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metadata_indexing_exclude",
+ "display_name": "Metadata Indexing Exclude",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional list of metadata fields to exclude from the indexing.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "metadata_indexing_include": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metadata_indexing_include",
+ "display_name": "Metadata Indexing Include",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional list of metadata fields to include in the indexing.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "metric": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "metric",
+ "display_name": "Metric",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional distance metric for vector comparisons in the vector store.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "namespace": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "namespace",
+ "display_name": "Namespace",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Optional namespace within Astra DB to use for the collection.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "pre_delete_collection": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "pre_delete_collection",
+ "display_name": "Pre Delete Collection",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "setup_mode": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "Async",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "Sync",
+ "Async",
+ "Off"
+ ],
+ "name": "setup_mode",
+ "display_name": "Setup Mode",
+ "advanced": true,
+ "dynamic": false,
+ "info": "Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "token": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "token",
+ "display_name": "Token",
+ "advanced": false,
+ "dynamic": false,
+ "info": "Authentication token for accessing Astra DB.",
+ "load_from_db": true,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": "ASTRA_DB_APPLICATION_TOKEN"
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Builds or loads an Astra DB Vector Store.",
+ "icon": "AstraDB",
+ "base_classes": [
+ "VectorStore"
+ ],
+ "display_name": "Astra DB",
+ "documentation": "",
+ "custom_fields": {
+ "embedding": null,
+ "token": null,
+ "api_endpoint": null,
+ "collection_name": null,
+ "inputs": null,
+ "namespace": null,
+ "metric": null,
+ "batch_size": null,
+ "bulk_insert_batch_concurrency": null,
+ "bulk_insert_overwrite_concurrency": null,
+ "bulk_delete_concurrency": null,
+ "setup_mode": null,
+ "pre_delete_collection": null,
+ "metadata_indexing_include": null,
+ "metadata_indexing_exclude": null,
+ "collection_indexing_policy": null
+ },
+ "output_types": [
+ "VectorStore"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [
+ "token",
+ "api_endpoint",
+ "collection_name",
+ "inputs",
+ "embedding"
+ ],
+ "beta": false
+ },
+ "id": "AstraDB-eUCSS"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 573,
+ "positionAbsolute": {
+ "x": 3372.04958055989,
+ "y": 1611.0742035495277
+ },
+ "dragging": false
},
- "output_types": ["Record"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "RecursiveCharacterTextSplitter-tR9QM"
- },
- "selected": false,
- "width": 384,
- "height": 501,
- "positionAbsolute": {
- "x": 2791.013514133929,
- "y": 1462.9588953494142
- },
- "dragging": false
- },
- {
- "id": "AstraDBSearch-41nRz",
- "type": "genericNode",
- "position": {
- "x": 1723.976434815103,
- "y": 277.03317407245913
- },
- "data": {
- "type": "AstraDBSearch",
- "node": {
- "template": {
- "embedding": {
- "type": "Embeddings",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "embedding",
- "display_name": "Embedding",
- "advanced": false,
- "dynamic": false,
- "info": "Embedding to use",
- "load_from_db": false,
- "title_case": false
- },
- "input_value": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "input_value",
- "display_name": "Input Value",
- "advanced": false,
- "dynamic": false,
- "info": "Input value to search",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "api_endpoint": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "api_endpoint",
- "display_name": "API Endpoint",
- "advanced": false,
- "dynamic": false,
- "info": "API endpoint URL for the Astra DB service.",
- "load_from_db": true,
- "title_case": false,
- "input_types": ["Text"],
- "value": "ASTRA_DB_API_ENDPOINT"
- },
- "batch_size": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "batch_size",
- "display_name": "Batch Size",
- "advanced": true,
- "dynamic": false,
- "info": "Optional number of records to process in a single batch.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_delete_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_delete_concurrency",
- "display_name": "Bulk Delete Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk delete operations.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_insert_batch_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_insert_batch_concurrency",
- "display_name": "Bulk Insert Batch Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk insert operations.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_insert_overwrite_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_insert_overwrite_concurrency",
- "display_name": "Bulk Insert Overwrite Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import List, Optional\n\nfrom langflow.components.vectorstores.AstraDB import AstraDBVectorStoreComponent\nfrom langflow.components.vectorstores.base.model import LCVectorStoreComponent\nfrom langflow.field_typing import Embeddings, Text\nfrom langflow.schema import Record\n\n\nclass AstraDBSearchComponent(LCVectorStoreComponent):\n display_name = \"Astra DB Search\"\n description = \"Searches an existing Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"input_value\", \"embedding\"]\n\n def build_config(self):\n return {\n \"search_type\": {\n \"display_name\": \"Search Type\",\n \"options\": [\"Similarity\", \"MMR\"],\n },\n \"input_value\": {\n \"display_name\": \"Input Value\",\n \"info\": \"Input value to search\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n \"number_of_results\": {\n \"display_name\": \"Number of Results\",\n \"info\": \"Number of results to return.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n collection_name: str,\n input_value: Text,\n token: str,\n api_endpoint: str,\n search_type: str = \"Similarity\",\n number_of_results: int = 4,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> List[Record]:\n vector_store = AstraDBVectorStoreComponent().build(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n try:\n return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)\n except KeyError as e:\n if \"content\" in str(e):\n raise ValueError(\n \"You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'.\"\n )\n else:\n raise e\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "collection_indexing_policy": {
- "type": "dict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "collection_indexing_policy",
- "display_name": "Collection Indexing Policy",
- "advanced": true,
- "dynamic": false,
- "info": "Optional dictionary defining the indexing policy for the collection.",
- "load_from_db": false,
- "title_case": false
- },
- "collection_name": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "collection_name",
- "display_name": "Collection Name",
- "advanced": false,
- "dynamic": false,
- "info": "The name of the collection within Astra DB where the vectors will be stored.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"],
- "value": "langflow"
- },
- "metadata_indexing_exclude": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metadata_indexing_exclude",
- "display_name": "Metadata Indexing Exclude",
- "advanced": true,
- "dynamic": false,
- "info": "Optional list of metadata fields to exclude from the indexing.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "metadata_indexing_include": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metadata_indexing_include",
- "display_name": "Metadata Indexing Include",
- "advanced": true,
- "dynamic": false,
- "info": "Optional list of metadata fields to include in the indexing.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "metric": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metric",
- "display_name": "Metric",
- "advanced": true,
- "dynamic": false,
- "info": "Optional distance metric for vector comparisons in the vector store.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "namespace": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "namespace",
- "display_name": "Namespace",
- "advanced": true,
- "dynamic": false,
- "info": "Optional namespace within Astra DB to use for the collection.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "number_of_results": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 4,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "number_of_results",
- "display_name": "Number of Results",
- "advanced": true,
- "dynamic": false,
- "info": "Number of results to return.",
- "load_from_db": false,
- "title_case": false
- },
- "pre_delete_collection": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "pre_delete_collection",
- "display_name": "Pre Delete Collection",
- "advanced": true,
- "dynamic": false,
- "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
- "load_from_db": false,
- "title_case": false
- },
- "search_type": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "Similarity",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": ["Similarity", "MMR"],
- "name": "search_type",
- "display_name": "Search Type",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "setup_mode": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "Sync",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": ["Sync", "Async", "Off"],
- "name": "setup_mode",
- "display_name": "Setup Mode",
- "advanced": true,
- "dynamic": false,
- "info": "Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "token": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "token",
- "display_name": "Token",
- "advanced": false,
- "dynamic": false,
- "info": "Authentication token for accessing Astra DB.",
- "load_from_db": true,
- "title_case": false,
- "input_types": ["Text"],
- "value": "ASTRA_DB_APPLICATION_TOKEN"
- },
- "_type": "CustomComponent"
+ {
+ "id": "OpenAIEmbeddings-9TPjc",
+ "type": "genericNode",
+ "position": {
+ "x": 2814.0402191223047,
+ "y": 1955.9268168273086
+ },
+ "data": {
+ "type": "OpenAIEmbeddings",
+ "node": {
+ "template": {
+ "allowed_special": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": [],
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "allowed_special",
+ "display_name": "Allowed Special",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "chunk_size": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 1000,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "chunk_size",
+ "display_name": "Chunk Size",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "client": {
+ "type": "Any",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "client",
+ "display_name": "Client",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "code": {
+ "type": "code",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": true,
+ "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "code",
+ "advanced": true,
+ "dynamic": true,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "default_headers": {
+ "type": "dict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "default_headers",
+ "display_name": "Default Headers",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "default_query": {
+ "type": "NestedDict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": {},
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "default_query",
+ "display_name": "Default Query",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "deployment": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": "text-embedding-ada-002",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "deployment",
+ "display_name": "Deployment",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "disallowed_special": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": [
+ "all"
+ ],
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "disallowed_special",
+ "display_name": "Disallowed Special",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "embedding_ctx_length": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 8191,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "embedding_ctx_length",
+ "display_name": "Embedding Context Length",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "max_retries": {
+ "type": "int",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": 6,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "max_retries",
+ "display_name": "Max Retries",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "model": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": true,
+ "show": true,
+ "multiline": false,
+ "value": "text-embedding-ada-002",
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "options": [
+ "text-embedding-3-small",
+ "text-embedding-3-large",
+ "text-embedding-ada-002"
+ ],
+ "name": "model",
+ "display_name": "Model",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "model_kwargs": {
+ "type": "NestedDict",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": {},
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "model_kwargs",
+ "display_name": "Model Kwargs",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "openai_api_base": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_base",
+ "display_name": "OpenAI API Base",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_key": {
+ "type": "str",
+ "required": true,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_key",
+ "display_name": "OpenAI API Key",
+ "advanced": false,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ],
+ "value": ""
+ },
+ "openai_api_type": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": true,
+ "name": "openai_api_type",
+ "display_name": "OpenAI API Type",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_api_version": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_api_version",
+ "display_name": "OpenAI API Version",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_organization": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_organization",
+ "display_name": "OpenAI Organization",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "openai_proxy": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "openai_proxy",
+ "display_name": "OpenAI Proxy",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "request_timeout": {
+ "type": "float",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "request_timeout",
+ "display_name": "Request Timeout",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "rangeSpec": {
+ "step_type": "float",
+ "min": -1,
+ "max": 1,
+ "step": 0.1
+ },
+ "load_from_db": false,
+ "title_case": false
+ },
+ "show_progress_bar": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "show_progress_bar",
+ "display_name": "Show Progress Bar",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "skip_empty": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "skip_empty",
+ "display_name": "Skip Empty",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "tiktoken_enable": {
+ "type": "bool",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "value": true,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "tiktoken_enable",
+ "display_name": "TikToken Enable",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false
+ },
+ "tiktoken_model_name": {
+ "type": "str",
+ "required": false,
+ "placeholder": "",
+ "list": false,
+ "show": true,
+ "multiline": false,
+ "fileTypes": [],
+ "file_path": "",
+ "password": false,
+ "name": "tiktoken_model_name",
+ "display_name": "TikToken Model Name",
+ "advanced": true,
+ "dynamic": false,
+ "info": "",
+ "load_from_db": false,
+ "title_case": false,
+ "input_types": [
+ "Text"
+ ]
+ },
+ "_type": "CustomComponent"
+ },
+ "description": "Generate embeddings using OpenAI models.",
+ "base_classes": [
+ "Embeddings"
+ ],
+ "display_name": "OpenAI Embeddings",
+ "documentation": "",
+ "custom_fields": {
+ "openai_api_key": null,
+ "default_headers": null,
+ "default_query": null,
+ "allowed_special": null,
+ "disallowed_special": null,
+ "chunk_size": null,
+ "client": null,
+ "deployment": null,
+ "embedding_ctx_length": null,
+ "max_retries": null,
+ "model": null,
+ "model_kwargs": null,
+ "openai_api_base": null,
+ "openai_api_type": null,
+ "openai_api_version": null,
+ "openai_organization": null,
+ "openai_proxy": null,
+ "request_timeout": null,
+ "show_progress_bar": null,
+ "skip_empty": null,
+ "tiktoken_enable": null,
+ "tiktoken_model_name": null
+ },
+ "output_types": [
+ "Embeddings"
+ ],
+ "field_formatters": {},
+ "frozen": false,
+ "field_order": [],
+ "beta": false
+ },
+ "id": "OpenAIEmbeddings-9TPjc"
+ },
+ "selected": false,
+ "width": 384,
+ "height": 383,
+ "positionAbsolute": {
+ "x": 2814.0402191223047,
+ "y": 1955.9268168273086
+ },
+ "dragging": false
+ }
+ ],
+ "edges": [
+ {
+ "source": "TextOutput-BDknO",
+ "target": "Prompt-xeI6K",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153TextOutput\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153}",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153context\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "id": "reactflow__edge-TextOutput-BDknO{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153TextOutput\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153}-Prompt-xeI6K{\u0153fieldName\u0153:\u0153context\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "context",
+ "id": "Prompt-xeI6K",
+ "inputTypes": [
+ "Document",
+ "BaseOutputParser",
+ "Record",
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "dataType": "TextOutput",
+ "id": "TextOutput-BDknO"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "selected": false
},
- "description": "Searches an existing Astra DB Vector Store.",
- "icon": "AstraDB",
- "base_classes": ["Record"],
- "display_name": "Astra DB Search",
- "documentation": "",
- "custom_fields": {
- "embedding": null,
- "collection_name": null,
- "input_value": null,
- "token": null,
- "api_endpoint": null,
- "search_type": null,
- "number_of_results": null,
- "namespace": null,
- "metric": null,
- "batch_size": null,
- "bulk_insert_batch_concurrency": null,
- "bulk_insert_overwrite_concurrency": null,
- "bulk_delete_concurrency": null,
- "setup_mode": null,
- "pre_delete_collection": null,
- "metadata_indexing_include": null,
- "metadata_indexing_exclude": null,
- "collection_indexing_policy": null
+ {
+ "source": "ChatInput-yxMKE",
+ "target": "Prompt-xeI6K",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153question\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "id": "reactflow__edge-ChatInput-yxMKE{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}-Prompt-xeI6K{\u0153fieldName\u0153:\u0153question\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "question",
+ "id": "Prompt-xeI6K",
+ "inputTypes": [
+ "Document",
+ "BaseOutputParser",
+ "Record",
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Text",
+ "str",
+ "object",
+ "Record"
+ ],
+ "dataType": "ChatInput",
+ "id": "ChatInput-yxMKE"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "selected": false
},
- "output_types": ["Record"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [
- "token",
- "api_endpoint",
- "collection_name",
- "input_value",
- "embedding"
- ],
- "beta": false
- },
- "id": "AstraDBSearch-41nRz"
- },
- "selected": false,
- "width": 384,
- "height": 713,
- "dragging": false,
- "positionAbsolute": {
- "x": 1723.976434815103,
- "y": 277.03317407245913
+ {
+ "source": "Prompt-xeI6K",
+ "target": "OpenAIModel-EjXlN",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153Prompt\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153}",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "id": "reactflow__edge-Prompt-xeI6K{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153Prompt\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153}-OpenAIModel-EjXlN{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "input_value",
+ "id": "OpenAIModel-EjXlN",
+ "inputTypes": [
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "dataType": "Prompt",
+ "id": "Prompt-xeI6K"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "selected": false
+ },
+ {
+ "source": "OpenAIModel-EjXlN",
+ "target": "ChatOutput-Q39I8",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153OpenAIModel\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153}",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153ChatOutput-Q39I8\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "id": "reactflow__edge-OpenAIModel-EjXlN{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153OpenAIModel\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153}-ChatOutput-Q39I8{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153ChatOutput-Q39I8\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "input_value",
+ "id": "ChatOutput-Q39I8",
+ "inputTypes": [
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "object",
+ "Text",
+ "str"
+ ],
+ "dataType": "OpenAIModel",
+ "id": "OpenAIModel-EjXlN"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "selected": false
+ },
+ {
+ "source": "File-t0a6a",
+ "target": "RecursiveCharacterTextSplitter-tR9QM",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153File\u0153,\u0153id\u0153:\u0153File-t0a6a\u0153}",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153Record\u0153],\u0153type\u0153:\u0153Document\u0153}",
+ "id": "reactflow__edge-File-t0a6a{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153File\u0153,\u0153id\u0153:\u0153File-t0a6a\u0153}-RecursiveCharacterTextSplitter-tR9QM{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153Record\u0153],\u0153type\u0153:\u0153Document\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "inputs",
+ "id": "RecursiveCharacterTextSplitter-tR9QM",
+ "inputTypes": [
+ "Document",
+ "Record"
+ ],
+ "type": "Document"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Record"
+ ],
+ "dataType": "File",
+ "id": "File-t0a6a"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "selected": false
+ },
+ {
+ "source": "OpenAIEmbeddings-ZlOk1",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-ZlOk1\u0153}",
+ "target": "AstraDBSearch-41nRz",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "embedding",
+ "id": "AstraDBSearch-41nRz",
+ "inputTypes": null,
+ "type": "Embeddings"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Embeddings"
+ ],
+ "dataType": "OpenAIEmbeddings",
+ "id": "OpenAIEmbeddings-ZlOk1"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "id": "reactflow__edge-OpenAIEmbeddings-ZlOk1{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-ZlOk1\u0153}-AstraDBSearch-41nRz{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}"
+ },
+ {
+ "source": "ChatInput-yxMKE",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}",
+ "target": "AstraDBSearch-41nRz",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "input_value",
+ "id": "AstraDBSearch-41nRz",
+ "inputTypes": [
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Text",
+ "str",
+ "object",
+ "Record"
+ ],
+ "dataType": "ChatInput",
+ "id": "ChatInput-yxMKE"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "id": "reactflow__edge-ChatInput-yxMKE{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}-AstraDBSearch-41nRz{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}"
+ },
+ {
+ "source": "RecursiveCharacterTextSplitter-tR9QM",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153RecursiveCharacterTextSplitter\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153}",
+ "target": "AstraDB-eUCSS",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Record\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "inputs",
+ "id": "AstraDB-eUCSS",
+ "inputTypes": null,
+ "type": "Record"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Record"
+ ],
+ "dataType": "RecursiveCharacterTextSplitter",
+ "id": "RecursiveCharacterTextSplitter-tR9QM"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "id": "reactflow__edge-RecursiveCharacterTextSplitter-tR9QM{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153RecursiveCharacterTextSplitter\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153}-AstraDB-eUCSS{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Record\u0153}",
+ "selected": false
+ },
+ {
+ "source": "OpenAIEmbeddings-9TPjc",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-9TPjc\u0153}",
+ "target": "AstraDB-eUCSS",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "embedding",
+ "id": "AstraDB-eUCSS",
+ "inputTypes": null,
+ "type": "Embeddings"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Embeddings"
+ ],
+ "dataType": "OpenAIEmbeddings",
+ "id": "OpenAIEmbeddings-9TPjc"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "id": "reactflow__edge-OpenAIEmbeddings-9TPjc{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-9TPjc\u0153}-AstraDB-eUCSS{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
+ "selected": false
+ },
+ {
+ "source": "AstraDBSearch-41nRz",
+ "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153AstraDBSearch\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153}",
+ "target": "TextOutput-BDknO",
+ "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153,\u0153inputTypes\u0153:[\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
+ "data": {
+ "targetHandle": {
+ "fieldName": "input_value",
+ "id": "TextOutput-BDknO",
+ "inputTypes": [
+ "Record",
+ "Text"
+ ],
+ "type": "str"
+ },
+ "sourceHandle": {
+ "baseClasses": [
+ "Record"
+ ],
+ "dataType": "AstraDBSearch",
+ "id": "AstraDBSearch-41nRz"
+ }
+ },
+ "style": {
+ "stroke": "#555"
+ },
+ "className": "stroke-gray-900 stroke-connection",
+ "id": "reactflow__edge-AstraDBSearch-41nRz{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153AstraDBSearch\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153}-TextOutput-BDknO{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153,\u0153inputTypes\u0153:[\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}"
+ }
+ ],
+ "viewport": {
+ "x": -259.6782520315529,
+ "y": 90.3428735006047,
+ "zoom": 0.2687057134854984
}
- },
- {
- "id": "AstraDB-eUCSS",
- "type": "genericNode",
- "position": {
- "x": 3372.04958055989,
- "y": 1611.0742035495277
- },
- "data": {
- "type": "AstraDB",
- "node": {
- "template": {
- "embedding": {
- "type": "Embeddings",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "embedding",
- "display_name": "Embedding",
- "advanced": false,
- "dynamic": false,
- "info": "Embedding to use",
- "load_from_db": false,
- "title_case": false
- },
- "inputs": {
- "type": "Record",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "inputs",
- "display_name": "Inputs",
- "advanced": false,
- "dynamic": false,
- "info": "Optional list of records to be processed and stored in the vector store.",
- "load_from_db": false,
- "title_case": false
- },
- "api_endpoint": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "api_endpoint",
- "display_name": "API Endpoint",
- "advanced": false,
- "dynamic": false,
- "info": "API endpoint URL for the Astra DB service.",
- "load_from_db": true,
- "title_case": false,
- "input_types": ["Text"],
- "value": "ASTRA_DB_API_ENDPOINT"
- },
- "batch_size": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "batch_size",
- "display_name": "Batch Size",
- "advanced": true,
- "dynamic": false,
- "info": "Optional number of records to process in a single batch.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_delete_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_delete_concurrency",
- "display_name": "Bulk Delete Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk delete operations.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_insert_batch_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_insert_batch_concurrency",
- "display_name": "Bulk Insert Batch Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk insert operations.",
- "load_from_db": false,
- "title_case": false
- },
- "bulk_insert_overwrite_concurrency": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "bulk_insert_overwrite_concurrency",
- "display_name": "Bulk Insert Overwrite Concurrency",
- "advanced": true,
- "dynamic": false,
- "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import List, Optional\n\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Async\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> VectorStore:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "collection_indexing_policy": {
- "type": "dict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "collection_indexing_policy",
- "display_name": "Collection Indexing Policy",
- "advanced": true,
- "dynamic": false,
- "info": "Optional dictionary defining the indexing policy for the collection.",
- "load_from_db": false,
- "title_case": false
- },
- "collection_name": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "collection_name",
- "display_name": "Collection Name",
- "advanced": false,
- "dynamic": false,
- "info": "The name of the collection within Astra DB where the vectors will be stored.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"],
- "value": "langflow"
- },
- "metadata_indexing_exclude": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metadata_indexing_exclude",
- "display_name": "Metadata Indexing Exclude",
- "advanced": true,
- "dynamic": false,
- "info": "Optional list of metadata fields to exclude from the indexing.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "metadata_indexing_include": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metadata_indexing_include",
- "display_name": "Metadata Indexing Include",
- "advanced": true,
- "dynamic": false,
- "info": "Optional list of metadata fields to include in the indexing.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "metric": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "metric",
- "display_name": "Metric",
- "advanced": true,
- "dynamic": false,
- "info": "Optional distance metric for vector comparisons in the vector store.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "namespace": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "namespace",
- "display_name": "Namespace",
- "advanced": true,
- "dynamic": false,
- "info": "Optional namespace within Astra DB to use for the collection.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "pre_delete_collection": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "pre_delete_collection",
- "display_name": "Pre Delete Collection",
- "advanced": true,
- "dynamic": false,
- "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
- "load_from_db": false,
- "title_case": false
- },
- "setup_mode": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "Async",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": ["Sync", "Async", "Off"],
- "name": "setup_mode",
- "display_name": "Setup Mode",
- "advanced": true,
- "dynamic": false,
- "info": "Configuration mode for setting up the vector store, with options like \u201cSync\u201d, \u201cAsync\u201d, or \u201cOff\u201d.",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "token": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "token",
- "display_name": "Token",
- "advanced": false,
- "dynamic": false,
- "info": "Authentication token for accessing Astra DB.",
- "load_from_db": true,
- "title_case": false,
- "input_types": ["Text"],
- "value": "ASTRA_DB_APPLICATION_TOKEN"
- },
- "_type": "CustomComponent"
- },
- "description": "Builds or loads an Astra DB Vector Store.",
- "icon": "AstraDB",
- "base_classes": ["VectorStore"],
- "display_name": "Astra DB",
- "documentation": "",
- "custom_fields": {
- "embedding": null,
- "token": null,
- "api_endpoint": null,
- "collection_name": null,
- "inputs": null,
- "namespace": null,
- "metric": null,
- "batch_size": null,
- "bulk_insert_batch_concurrency": null,
- "bulk_insert_overwrite_concurrency": null,
- "bulk_delete_concurrency": null,
- "setup_mode": null,
- "pre_delete_collection": null,
- "metadata_indexing_include": null,
- "metadata_indexing_exclude": null,
- "collection_indexing_policy": null
- },
- "output_types": ["VectorStore"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [
- "token",
- "api_endpoint",
- "collection_name",
- "inputs",
- "embedding"
- ],
- "beta": false
- },
- "id": "AstraDB-eUCSS"
- },
- "selected": false,
- "width": 384,
- "height": 573,
- "positionAbsolute": {
- "x": 3372.04958055989,
- "y": 1611.0742035495277
- },
- "dragging": false
- },
- {
- "id": "OpenAIEmbeddings-9TPjc",
- "type": "genericNode",
- "position": {
- "x": 2814.0402191223047,
- "y": 1955.9268168273086
- },
- "data": {
- "type": "OpenAIEmbeddings",
- "node": {
- "template": {
- "allowed_special": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": [],
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "allowed_special",
- "display_name": "Allowed Special",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "chunk_size": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 1000,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "chunk_size",
- "display_name": "Chunk Size",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "client": {
- "type": "Any",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "client",
- "display_name": "Client",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "code": {
- "type": "code",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": true,
- "value": "from typing import Any, Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\n\nfrom langflow.field_typing import Embeddings, NestedDict\nfrom langflow.interface.custom.custom_component import CustomComponent\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n client: Optional[Any] = None,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n client=client,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=openai_api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "code",
- "advanced": true,
- "dynamic": true,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "default_headers": {
- "type": "dict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "default_headers",
- "display_name": "Default Headers",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "default_query": {
- "type": "NestedDict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": {},
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "default_query",
- "display_name": "Default Query",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "deployment": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": "text-embedding-ada-002",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "deployment",
- "display_name": "Deployment",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "disallowed_special": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": ["all"],
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "disallowed_special",
- "display_name": "Disallowed Special",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "embedding_ctx_length": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 8191,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "embedding_ctx_length",
- "display_name": "Embedding Context Length",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "max_retries": {
- "type": "int",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": 6,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "max_retries",
- "display_name": "Max Retries",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "model": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": true,
- "show": true,
- "multiline": false,
- "value": "text-embedding-ada-002",
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "options": [
- "text-embedding-3-small",
- "text-embedding-3-large",
- "text-embedding-ada-002"
- ],
- "name": "model",
- "display_name": "Model",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "model_kwargs": {
- "type": "NestedDict",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": {},
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "model_kwargs",
- "display_name": "Model Kwargs",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "openai_api_base": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_base",
- "display_name": "OpenAI API Base",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_key": {
- "type": "str",
- "required": true,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_key",
- "display_name": "OpenAI API Key",
- "advanced": false,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"],
- "value": ""
- },
- "openai_api_type": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": true,
- "name": "openai_api_type",
- "display_name": "OpenAI API Type",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_api_version": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_api_version",
- "display_name": "OpenAI API Version",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_organization": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_organization",
- "display_name": "OpenAI Organization",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "openai_proxy": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "openai_proxy",
- "display_name": "OpenAI Proxy",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "request_timeout": {
- "type": "float",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "request_timeout",
- "display_name": "Request Timeout",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "rangeSpec": {
- "step_type": "float",
- "min": -1,
- "max": 1,
- "step": 0.1
- },
- "load_from_db": false,
- "title_case": false
- },
- "show_progress_bar": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "show_progress_bar",
- "display_name": "Show Progress Bar",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "skip_empty": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "skip_empty",
- "display_name": "Skip Empty",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "tiktoken_enable": {
- "type": "bool",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "value": true,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "tiktoken_enable",
- "display_name": "TikToken Enable",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false
- },
- "tiktoken_model_name": {
- "type": "str",
- "required": false,
- "placeholder": "",
- "list": false,
- "show": true,
- "multiline": false,
- "fileTypes": [],
- "file_path": "",
- "password": false,
- "name": "tiktoken_model_name",
- "display_name": "TikToken Model Name",
- "advanced": true,
- "dynamic": false,
- "info": "",
- "load_from_db": false,
- "title_case": false,
- "input_types": ["Text"]
- },
- "_type": "CustomComponent"
- },
- "description": "Generate embeddings using OpenAI models.",
- "base_classes": ["Embeddings"],
- "display_name": "OpenAI Embeddings",
- "documentation": "",
- "custom_fields": {
- "openai_api_key": null,
- "default_headers": null,
- "default_query": null,
- "allowed_special": null,
- "disallowed_special": null,
- "chunk_size": null,
- "client": null,
- "deployment": null,
- "embedding_ctx_length": null,
- "max_retries": null,
- "model": null,
- "model_kwargs": null,
- "openai_api_base": null,
- "openai_api_type": null,
- "openai_api_version": null,
- "openai_organization": null,
- "openai_proxy": null,
- "request_timeout": null,
- "show_progress_bar": null,
- "skip_empty": null,
- "tiktoken_enable": null,
- "tiktoken_model_name": null
- },
- "output_types": ["Embeddings"],
- "field_formatters": {},
- "frozen": false,
- "field_order": [],
- "beta": false
- },
- "id": "OpenAIEmbeddings-9TPjc"
- },
- "selected": false,
- "width": 384,
- "height": 383,
- "positionAbsolute": {
- "x": 2814.0402191223047,
- "y": 1955.9268168273086
- },
- "dragging": false
- }
- ],
- "edges": [
- {
- "source": "TextOutput-BDknO",
- "target": "Prompt-xeI6K",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153TextOutput\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153}",
- "targetHandle": "{\u0153fieldName\u0153:\u0153context\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "id": "reactflow__edge-TextOutput-BDknO{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153TextOutput\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153}-Prompt-xeI6K{\u0153fieldName\u0153:\u0153context\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "context",
- "id": "Prompt-xeI6K",
- "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["object", "Text", "str"],
- "dataType": "TextOutput",
- "id": "TextOutput-BDknO"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "selected": false
- },
- {
- "source": "ChatInput-yxMKE",
- "target": "Prompt-xeI6K",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}",
- "targetHandle": "{\u0153fieldName\u0153:\u0153question\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "id": "reactflow__edge-ChatInput-yxMKE{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}-Prompt-xeI6K{\u0153fieldName\u0153:\u0153question\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153BaseOutputParser\u0153,\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "question",
- "id": "Prompt-xeI6K",
- "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["Text", "str", "object", "Record"],
- "dataType": "ChatInput",
- "id": "ChatInput-yxMKE"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "selected": false
- },
- {
- "source": "Prompt-xeI6K",
- "target": "OpenAIModel-EjXlN",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153Prompt\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153}",
- "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "id": "reactflow__edge-Prompt-xeI6K{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153Prompt\u0153,\u0153id\u0153:\u0153Prompt-xeI6K\u0153}-OpenAIModel-EjXlN{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "input_value",
- "id": "OpenAIModel-EjXlN",
- "inputTypes": ["Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["object", "Text", "str"],
- "dataType": "Prompt",
- "id": "Prompt-xeI6K"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "selected": false
- },
- {
- "source": "OpenAIModel-EjXlN",
- "target": "ChatOutput-Q39I8",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153OpenAIModel\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153}",
- "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153ChatOutput-Q39I8\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "id": "reactflow__edge-OpenAIModel-EjXlN{\u0153baseClasses\u0153:[\u0153object\u0153,\u0153Text\u0153,\u0153str\u0153],\u0153dataType\u0153:\u0153OpenAIModel\u0153,\u0153id\u0153:\u0153OpenAIModel-EjXlN\u0153}-ChatOutput-Q39I8{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153ChatOutput-Q39I8\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "input_value",
- "id": "ChatOutput-Q39I8",
- "inputTypes": ["Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["object", "Text", "str"],
- "dataType": "OpenAIModel",
- "id": "OpenAIModel-EjXlN"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "selected": false
- },
- {
- "source": "File-t0a6a",
- "target": "RecursiveCharacterTextSplitter-tR9QM",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153File\u0153,\u0153id\u0153:\u0153File-t0a6a\u0153}",
- "targetHandle": "{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153Record\u0153],\u0153type\u0153:\u0153Document\u0153}",
- "id": "reactflow__edge-File-t0a6a{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153File\u0153,\u0153id\u0153:\u0153File-t0a6a\u0153}-RecursiveCharacterTextSplitter-tR9QM{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153,\u0153inputTypes\u0153:[\u0153Document\u0153,\u0153Record\u0153],\u0153type\u0153:\u0153Document\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "inputs",
- "id": "RecursiveCharacterTextSplitter-tR9QM",
- "inputTypes": ["Document", "Record"],
- "type": "Document"
- },
- "sourceHandle": {
- "baseClasses": ["Record"],
- "dataType": "File",
- "id": "File-t0a6a"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "selected": false
- },
- {
- "source": "OpenAIEmbeddings-ZlOk1",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-ZlOk1\u0153}",
- "target": "AstraDBSearch-41nRz",
- "targetHandle": "{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "embedding",
- "id": "AstraDBSearch-41nRz",
- "inputTypes": null,
- "type": "Embeddings"
- },
- "sourceHandle": {
- "baseClasses": ["Embeddings"],
- "dataType": "OpenAIEmbeddings",
- "id": "OpenAIEmbeddings-ZlOk1"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "id": "reactflow__edge-OpenAIEmbeddings-ZlOk1{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-ZlOk1\u0153}-AstraDBSearch-41nRz{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}"
- },
- {
- "source": "ChatInput-yxMKE",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}",
- "target": "AstraDBSearch-41nRz",
- "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "input_value",
- "id": "AstraDBSearch-41nRz",
- "inputTypes": ["Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["Text", "str", "object", "Record"],
- "dataType": "ChatInput",
- "id": "ChatInput-yxMKE"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "id": "reactflow__edge-ChatInput-yxMKE{\u0153baseClasses\u0153:[\u0153Text\u0153,\u0153str\u0153,\u0153object\u0153,\u0153Record\u0153],\u0153dataType\u0153:\u0153ChatInput\u0153,\u0153id\u0153:\u0153ChatInput-yxMKE\u0153}-AstraDBSearch-41nRz{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153,\u0153inputTypes\u0153:[\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}"
- },
- {
- "source": "RecursiveCharacterTextSplitter-tR9QM",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153RecursiveCharacterTextSplitter\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153}",
- "target": "AstraDB-eUCSS",
- "targetHandle": "{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Record\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "inputs",
- "id": "AstraDB-eUCSS",
- "inputTypes": null,
- "type": "Record"
- },
- "sourceHandle": {
- "baseClasses": ["Record"],
- "dataType": "RecursiveCharacterTextSplitter",
- "id": "RecursiveCharacterTextSplitter-tR9QM"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "id": "reactflow__edge-RecursiveCharacterTextSplitter-tR9QM{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153RecursiveCharacterTextSplitter\u0153,\u0153id\u0153:\u0153RecursiveCharacterTextSplitter-tR9QM\u0153}-AstraDB-eUCSS{\u0153fieldName\u0153:\u0153inputs\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Record\u0153}",
- "selected": false
- },
- {
- "source": "OpenAIEmbeddings-9TPjc",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-9TPjc\u0153}",
- "target": "AstraDB-eUCSS",
- "targetHandle": "{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "embedding",
- "id": "AstraDB-eUCSS",
- "inputTypes": null,
- "type": "Embeddings"
- },
- "sourceHandle": {
- "baseClasses": ["Embeddings"],
- "dataType": "OpenAIEmbeddings",
- "id": "OpenAIEmbeddings-9TPjc"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "id": "reactflow__edge-OpenAIEmbeddings-9TPjc{\u0153baseClasses\u0153:[\u0153Embeddings\u0153],\u0153dataType\u0153:\u0153OpenAIEmbeddings\u0153,\u0153id\u0153:\u0153OpenAIEmbeddings-9TPjc\u0153}-AstraDB-eUCSS{\u0153fieldName\u0153:\u0153embedding\u0153,\u0153id\u0153:\u0153AstraDB-eUCSS\u0153,\u0153inputTypes\u0153:null,\u0153type\u0153:\u0153Embeddings\u0153}",
- "selected": false
- },
- {
- "source": "AstraDBSearch-41nRz",
- "sourceHandle": "{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153AstraDBSearch\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153}",
- "target": "TextOutput-BDknO",
- "targetHandle": "{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153,\u0153inputTypes\u0153:[\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}",
- "data": {
- "targetHandle": {
- "fieldName": "input_value",
- "id": "TextOutput-BDknO",
- "inputTypes": ["Record", "Text"],
- "type": "str"
- },
- "sourceHandle": {
- "baseClasses": ["Record"],
- "dataType": "AstraDBSearch",
- "id": "AstraDBSearch-41nRz"
- }
- },
- "style": {
- "stroke": "#555"
- },
- "className": "stroke-gray-900 stroke-connection",
- "id": "reactflow__edge-AstraDBSearch-41nRz{\u0153baseClasses\u0153:[\u0153Record\u0153],\u0153dataType\u0153:\u0153AstraDBSearch\u0153,\u0153id\u0153:\u0153AstraDBSearch-41nRz\u0153}-TextOutput-BDknO{\u0153fieldName\u0153:\u0153input_value\u0153,\u0153id\u0153:\u0153TextOutput-BDknO\u0153,\u0153inputTypes\u0153:[\u0153Record\u0153,\u0153Text\u0153],\u0153type\u0153:\u0153str\u0153}"
- }
- ],
- "viewport": {
- "x": -259.6782520315529,
- "y": 90.3428735006047,
- "zoom": 0.2687057134854984
- }
- },
- "description": "Visit https://pre-release.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.",
- "name": "Vector Store RAG",
- "last_tested_version": "1.0.0a0",
- "is_component": false
+ },
+ "description": "Visit https://pre-release.langflow.org/tutorials/rag-with-astradb for a detailed guide of this project.\nThis project give you both Ingestion and RAG in a single file. You'll need to visit https://astra.datastax.com/ to create an Astra DB instance, your Token and grab an API Endpoint.\nRunning this project requires you to add a file in the Files component, then define a Collection Name and click on the Play icon on the Astra DB component. \n\nAfter the ingestion ends you are ready to click on the Run button at the lower left corner and start asking questions about your data.",
+ "name": "Vector Store RAG",
+ "last_tested_version": "1.0.0a0",
+ "is_component": false
}
diff --git a/docs/static/img/notion/AddContentToPage_flow_example.png b/docs/static/img/notion/AddContentToPage_flow_example.png
new file mode 100644
index 000000000..31aadb080
Binary files /dev/null and b/docs/static/img/notion/AddContentToPage_flow_example.png differ
diff --git a/docs/static/img/notion/AddContentToPage_flow_example_dark.png b/docs/static/img/notion/AddContentToPage_flow_example_dark.png
new file mode 100644
index 000000000..0d8809209
Binary files /dev/null and b/docs/static/img/notion/AddContentToPage_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionDatabaseProperties_flow_example.png b/docs/static/img/notion/NotionDatabaseProperties_flow_example.png
new file mode 100644
index 000000000..6ec3d7ac1
Binary files /dev/null and b/docs/static/img/notion/NotionDatabaseProperties_flow_example.png differ
diff --git a/docs/static/img/notion/NotionDatabaseProperties_flow_example_dark.png b/docs/static/img/notion/NotionDatabaseProperties_flow_example_dark.png
new file mode 100644
index 000000000..4d3a5a2c9
Binary files /dev/null and b/docs/static/img/notion/NotionDatabaseProperties_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionListPages_flow_example.png b/docs/static/img/notion/NotionListPages_flow_example.png
new file mode 100644
index 000000000..c04e3d857
Binary files /dev/null and b/docs/static/img/notion/NotionListPages_flow_example.png differ
diff --git a/docs/static/img/notion/NotionListPages_flow_example_dark.png b/docs/static/img/notion/NotionListPages_flow_example_dark.png
new file mode 100644
index 000000000..ee041bde7
Binary files /dev/null and b/docs/static/img/notion/NotionListPages_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionPageContent_flow_example.png b/docs/static/img/notion/NotionPageContent_flow_example.png
new file mode 100644
index 000000000..5d89af125
Binary files /dev/null and b/docs/static/img/notion/NotionPageContent_flow_example.png differ
diff --git a/docs/static/img/notion/NotionPageContent_flow_example_dark.png b/docs/static/img/notion/NotionPageContent_flow_example_dark.png
new file mode 100644
index 000000000..144c1e0ed
Binary files /dev/null and b/docs/static/img/notion/NotionPageContent_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionPageCreator_flow_example.png b/docs/static/img/notion/NotionPageCreator_flow_example.png
new file mode 100644
index 000000000..1cc14788a
Binary files /dev/null and b/docs/static/img/notion/NotionPageCreator_flow_example.png differ
diff --git a/docs/static/img/notion/NotionPageCreator_flow_example_dark.png b/docs/static/img/notion/NotionPageCreator_flow_example_dark.png
new file mode 100644
index 000000000..97788dbc0
Binary files /dev/null and b/docs/static/img/notion/NotionPageCreator_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionPageUpdate_flow_example.png b/docs/static/img/notion/NotionPageUpdate_flow_example.png
new file mode 100644
index 000000000..dd02f9bba
Binary files /dev/null and b/docs/static/img/notion/NotionPageUpdate_flow_example.png differ
diff --git a/docs/static/img/notion/NotionPageUpdate_flow_example_dark.png b/docs/static/img/notion/NotionPageUpdate_flow_example_dark.png
new file mode 100644
index 000000000..bc37ff236
Binary files /dev/null and b/docs/static/img/notion/NotionPageUpdate_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionSearch_flow_example.png b/docs/static/img/notion/NotionSearch_flow_example.png
new file mode 100644
index 000000000..95e6c72a7
Binary files /dev/null and b/docs/static/img/notion/NotionSearch_flow_example.png differ
diff --git a/docs/static/img/notion/NotionSearch_flow_example_dark.png b/docs/static/img/notion/NotionSearch_flow_example_dark.png
new file mode 100644
index 000000000..924aff55b
Binary files /dev/null and b/docs/static/img/notion/NotionSearch_flow_example_dark.png differ
diff --git a/docs/static/img/notion/NotionUserList_flow_example.png b/docs/static/img/notion/NotionUserList_flow_example.png
new file mode 100644
index 000000000..e0fbd8579
Binary files /dev/null and b/docs/static/img/notion/NotionUserList_flow_example.png differ
diff --git a/docs/static/img/notion/NotionUserList_flow_example_dark.png b/docs/static/img/notion/NotionUserList_flow_example_dark.png
new file mode 100644
index 000000000..d59e7d9a8
Binary files /dev/null and b/docs/static/img/notion/NotionUserList_flow_example_dark.png differ
diff --git a/docs/static/img/notion/notion_components_bundle.png b/docs/static/img/notion/notion_components_bundle.png
new file mode 100644
index 000000000..f924ed14a
Binary files /dev/null and b/docs/static/img/notion/notion_components_bundle.png differ
diff --git a/docs/static/img/notion/notion_components_bundle_dark.png b/docs/static/img/notion/notion_components_bundle_dark.png
new file mode 100644
index 000000000..048646bdb
Binary files /dev/null and b/docs/static/img/notion/notion_components_bundle_dark.png differ
diff --git a/docs/static/json_files/Notion_Components_bundle.json b/docs/static/json_files/Notion_Components_bundle.json
new file mode 100644
index 000000000..21181187c
--- /dev/null
+++ b/docs/static/json_files/Notion_Components_bundle.json
@@ -0,0 +1 @@
+{"id":"7cd51434-9767-450f-8742-27857367f8c2","data":{"nodes":[{"id":"RecordsToText-Q69g5","type":"genericNode","position":{"x":-2671.5528488127866,"y":-963.4266471378126},"data":{"type":"RecordsToText","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\r\nfrom typing import List\r\n\r\nfrom langflow import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\n\r\nclass NotionUserList(CustomComponent):\r\n display_name = \"List Users [Notion]\"\r\n description = \"Retrieve users from Notion.\"\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/list-users\"\r\n icon = \"NotionDirectoryLoader\"\r\n \r\n def build_config(self):\r\n return {\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n notion_secret: str,\r\n ) -> List[Record]:\r\n url = \"https://api.notion.com/v1/users\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Notion-Version\": \"2022-06-28\",\r\n }\r\n\r\n response = requests.get(url, headers=headers)\r\n response.raise_for_status()\r\n\r\n data = response.json()\r\n results = data['results']\r\n\r\n records = []\r\n for user in results:\r\n id = user['id']\r\n type = user['type']\r\n name = user.get('name', '')\r\n avatar_url = user.get('avatar_url', '')\r\n\r\n record_data = {\r\n \"id\": id,\r\n \"type\": type,\r\n \"name\": name,\r\n \"avatar_url\": avatar_url,\r\n }\r\n\r\n output = \"User:\\n\"\r\n for key, value in record_data.items():\r\n output += f\"{key.replace('_', ' ').title()}: {value}\\n\"\r\n output += \"________________________\\n\"\r\n\r\n record = Record(text=output, data=record_data)\r\n records.append(record)\r\n\r\n self.status = \"\\n\".join(record.text for record in records)\r\n return records","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":false,"title_case":false,"input_types":["Text"],"value":""},"_type":"CustomComponent"},"description":"Retrieve users from Notion.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"List Users [Notion] ","documentation":"https://docs.langflow.org/integrations/notion/list-users","custom_fields":{"notion_secret":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false},"id":"RecordsToText-Q69g5","description":"Retrieve users from Notion.","display_name":"List Users [Notion] "},"selected":false,"width":384,"height":289,"dragging":false,"positionAbsolute":{"x":-2671.5528488127866,"y":-963.4266471378126}},{"id":"CustomComponent-PU0K5","type":"genericNode","position":{"x":-3077.2269116193215,"y":-960.9450220159636},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\r\nfrom typing import Optional\r\n\r\nimport requests\r\nfrom langflow.custom import CustomComponent\r\n\r\n\r\nclass NotionPageCreator(CustomComponent):\r\n display_name = \"Create Page [Notion]\"\r\n description = \"A component for creating Notion pages.\"\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/page-create\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n def build_config(self):\r\n return {\r\n \"database_id\": {\r\n \"display_name\": \"Database ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the Notion database.\",\r\n },\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n \"properties\": {\r\n \"display_name\": \"Properties\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}\",\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n database_id: str,\r\n notion_secret: str,\r\n properties: str = '{\"Task name\": {\"id\": \"title\", \"type\": \"title\", \"title\": [{\"type\": \"text\", \"text\": {\"content\": \"Send Notion Components to LF\", \"link\": null}}]}}',\r\n ) -> str:\r\n if not database_id or not properties:\r\n raise ValueError(\"Invalid input. Please provide 'database_id' and 'properties'.\")\r\n\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Content-Type\": \"application/json\",\r\n \"Notion-Version\": \"2022-06-28\",\r\n }\r\n\r\n data = {\r\n \"parent\": {\"database_id\": database_id},\r\n \"properties\": json.loads(properties),\r\n }\r\n\r\n response = requests.post(\"https://api.notion.com/v1/pages\", headers=headers, json=data)\r\n\r\n if response.status_code == 200:\r\n page_id = response.json()[\"id\"]\r\n self.status = f\"Successfully created Notion page with ID: {page_id}\\n {str(response.json())}\"\r\n return response.json()\r\n else:\r\n error_message = f\"Failed to create Notion page. Status code: {response.status_code}, Error: {response.text}\"\r\n self.status = error_message\r\n raise Exception(error_message)","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"database_id","display_name":"Database ID","advanced":false,"dynamic":false,"info":"The ID of the Notion database.","load_from_db":false,"title_case":false,"input_types":["Text"]},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":false,"title_case":false,"input_types":["Text"],"value":""},"properties":{"type":"str","required":false,"placeholder":"","list":false,"show":true,"multiline":false,"value":"{\"Task name\": {\"id\": \"title\", \"type\": \"title\", \"title\": [{\"type\": \"text\", \"text\": {\"content\": \"Send Notion Components to LF\", \"link\": null}}]}}","fileTypes":[],"file_path":"","password":false,"name":"properties","display_name":"Properties","advanced":false,"dynamic":false,"info":"The properties of the new page. Depending on your database setup, this can change. E.G: {'Task name': {'id': 'title', 'type': 'title', 'title': [{'type': 'text', 'text': {'content': 'Send Notion Components to LF', 'link': null}}]}}","load_from_db":false,"title_case":false,"input_types":["Text"]},"_type":"CustomComponent"},"description":"A component for creating Notion pages.","icon":"NotionDirectoryLoader","base_classes":["object","str","Text"],"display_name":"Create Page [Notion] ","documentation":"https://docs.langflow.org/integrations/notion/page-create","custom_fields":{"database_id":null,"notion_secret":null,"properties":null},"output_types":["Text"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false},"id":"CustomComponent-PU0K5","description":"A component for creating Notion pages.","display_name":"Create Page [Notion] "},"selected":false,"width":384,"height":477,"positionAbsolute":{"x":-3077.2269116193215,"y":-960.9450220159636},"dragging":false},{"id":"CustomComponent-YODla","type":"genericNode","position":{"x":-3485.297183150799,"y":-362.8525892356713},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\r\nfrom typing import Dict\r\n\r\nfrom langflow import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\n\r\nclass NotionDatabaseProperties(CustomComponent):\r\n display_name = \"List Database Properties [Notion]\"\r\n description = \"Retrieve properties of a Notion database.\"\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/list-database-properties\"\r\n icon = \"NotionDirectoryLoader\"\r\n \r\n def build_config(self):\r\n return {\r\n \"database_id\": {\r\n \"display_name\": \"Database ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the Notion database.\",\r\n },\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n database_id: str,\r\n notion_secret: str,\r\n ) -> Record:\r\n url = f\"https://api.notion.com/v1/databases/{database_id}\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Notion-Version\": \"2022-06-28\", # Use the latest supported version\r\n }\r\n\r\n response = requests.get(url, headers=headers)\r\n response.raise_for_status()\r\n\r\n data = response.json()\r\n properties = data.get(\"properties\", {})\r\n\r\n record = Record(text=str(response.json()), data=properties)\r\n self.status = f\"Retrieved {len(properties)} properties from the Notion database.\\n {record.text}\"\r\n return record","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"database_id","display_name":"Database ID","advanced":false,"dynamic":false,"info":"The ID of the Notion database.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":"NOTION_NMSTX_DB_ID"},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"_type":"CustomComponent"},"description":"Retrieve properties of a Notion database.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"List Database Properties [Notion] ","documentation":"https://docs.langflow.org/integrations/notion/list-database-properties","custom_fields":{"database_id":null,"notion_secret":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false},"id":"CustomComponent-YODla","description":"Retrieve properties of a Notion database.","display_name":"List Database Properties [Notion] "},"selected":true,"width":384,"height":383,"dragging":false,"positionAbsolute":{"x":-3485.297183150799,"y":-362.8525892356713}},{"id":"CustomComponent-wHlSz","type":"genericNode","position":{"x":-2668.7714642455403,"y":-657.2376228212606},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\r\nimport requests\r\nfrom typing import Dict, Any\r\n\r\nfrom langflow import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\n\r\nclass NotionPageUpdate(CustomComponent):\r\n display_name = \"Update Page Property [Notion]\"\r\n description = \"Update the properties of a Notion page.\"\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/page-update\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n def build_config(self):\r\n return {\r\n \"page_id\": {\r\n \"display_name\": \"Page ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the Notion page to update.\",\r\n },\r\n \"properties\": {\r\n \"display_name\": \"Properties\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The properties to update on the page (as a JSON string).\",\r\n \"multiline\": True,\r\n },\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n page_id: str,\r\n properties: str,\r\n notion_secret: str,\r\n ) -> Record:\r\n url = f\"https://api.notion.com/v1/pages/{page_id}\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Content-Type\": \"application/json\",\r\n \"Notion-Version\": \"2022-06-28\", # Use the latest supported version\r\n }\r\n\r\n try:\r\n parsed_properties = json.loads(properties)\r\n except json.JSONDecodeError as e:\r\n raise ValueError(\"Invalid JSON format for properties\") from e\r\n\r\n data = {\r\n \"properties\": parsed_properties\r\n }\r\n\r\n response = requests.patch(url, headers=headers, json=data)\r\n response.raise_for_status()\r\n\r\n updated_page = response.json()\r\n\r\n output = \"Updated page properties:\\n\"\r\n for prop_name, prop_value in updated_page[\"properties\"].items():\r\n output += f\"{prop_name}: {prop_value}\\n\"\r\n\r\n self.status = output\r\n return Record(data=updated_page)","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"page_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"page_id","display_name":"Page ID","advanced":false,"dynamic":false,"info":"The ID of the Notion page to update.","load_from_db":false,"title_case":false,"input_types":["Text"]},"properties":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"fileTypes":[],"file_path":"","password":false,"name":"properties","display_name":"Properties","advanced":false,"dynamic":false,"info":"The properties to update on the page (as a JSON string).","load_from_db":false,"title_case":false,"input_types":["Text"],"value":"{ \"title\": [ { \"text\": { \"content\": \"Test Page\" } } ] }"},"_type":"CustomComponent"},"description":"Update the properties of a Notion page.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"Update Page Property [Notion]","documentation":"https://docs.langflow.org/integrations/notion/page-update","custom_fields":{"page_id":null,"properties":null,"notion_secret":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false},"id":"CustomComponent-wHlSz","description":"Update the properties of a Notion page.","display_name":"Update Page Property [Notion]"},"selected":false,"width":384,"height":477,"dragging":false,"positionAbsolute":{"x":-2668.7714642455403,"y":-657.2376228212606}},{"id":"CustomComponent-oelYw","type":"genericNode","position":{"x":-2253.1007124701327,"y":-448.47240118604134},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\r\nfrom typing import Dict, Any\r\n\r\nfrom langflow import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\n\r\nclass NotionPageContent(CustomComponent):\r\n display_name = \"Page Content Viewer [Notion]\"\r\n description = \"Retrieve the content of a Notion page as plain text.\"\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/page-content-viewer\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n def build_config(self):\r\n return {\r\n \"page_id\": {\r\n \"display_name\": \"Page ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the Notion page to retrieve.\",\r\n },\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n page_id: str,\r\n notion_secret: str,\r\n ) -> Record:\r\n blocks_url = f\"https://api.notion.com/v1/blocks/{page_id}/children?page_size=100\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Notion-Version\": \"2022-06-28\", # Use the latest supported version\r\n }\r\n\r\n # Retrieve the child blocks\r\n blocks_response = requests.get(blocks_url, headers=headers)\r\n blocks_response.raise_for_status()\r\n blocks_data = blocks_response.json()\r\n\r\n # Parse the blocks and extract the content as plain text\r\n content = self.parse_blocks(blocks_data[\"results\"])\r\n\r\n self.status = content\r\n return Record(data={\"content\": content}, text=content)\r\n\r\n def parse_blocks(self, blocks: list) -> str:\r\n content = \"\"\r\n for block in blocks:\r\n block_type = block[\"type\"]\r\n if block_type in [\"paragraph\", \"heading_1\", \"heading_2\", \"heading_3\", \"quote\"]:\r\n content += self.parse_rich_text(block[block_type][\"rich_text\"]) + \"\\n\\n\"\r\n elif block_type in [\"bulleted_list_item\", \"numbered_list_item\"]:\r\n content += self.parse_rich_text(block[block_type][\"rich_text\"]) + \"\\n\"\r\n elif block_type == \"to_do\":\r\n content += self.parse_rich_text(block[\"to_do\"][\"rich_text\"]) + \"\\n\"\r\n elif block_type == \"code\":\r\n content += self.parse_rich_text(block[\"code\"][\"rich_text\"]) + \"\\n\\n\"\r\n elif block_type == \"image\":\r\n content += f\"[Image: {block['image']['external']['url']}]\\n\\n\"\r\n elif block_type == \"divider\":\r\n content += \"---\\n\\n\"\r\n return content.strip()\r\n\r\n def parse_rich_text(self, rich_text: list) -> str:\r\n text = \"\"\r\n for segment in rich_text:\r\n text += segment[\"plain_text\"]\r\n return text","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"page_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"page_id","display_name":"Page ID","advanced":false,"dynamic":false,"info":"The ID of the Notion page to retrieve.","load_from_db":false,"title_case":false,"input_types":["Text"]},"_type":"CustomComponent"},"description":"Retrieve the content of a Notion page as plain text.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"Page Content Viewer [Notion] ","documentation":"https://docs.langflow.org/integrations/notion/page-content-viewer","custom_fields":{"page_id":null,"notion_secret":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false},"id":"CustomComponent-oelYw","description":"Retrieve the content of a Notion page as plain text.","display_name":"Page Content Viewer [Notion] "},"selected":false,"width":384,"height":383,"positionAbsolute":{"x":-2253.1007124701327,"y":-448.47240118604134},"dragging":false},{"id":"CustomComponent-Pn52w","type":"genericNode","position":{"x":-3070.9222948695096,"y":-472.4537855763852},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\r\nimport json\r\nfrom typing import Dict, Any, List\r\nfrom langflow.custom import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\nclass NotionListPages(CustomComponent):\r\n display_name = \"List Pages [Notion]\"\r\n description = (\r\n \"Query a Notion database with filtering and sorting. \"\r\n \"The input should be a JSON string containing the 'filter' and 'sorts' objects. \"\r\n \"Example input:\\n\"\r\n '{\"filter\": {\"property\": \"Status\", \"select\": {\"equals\": \"Done\"}}, \"sorts\": [{\"timestamp\": \"created_time\", \"direction\": \"descending\"}]}'\r\n )\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/list-pages\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n field_order = [\r\n \"notion_secret\",\r\n \"database_id\",\r\n \"query_payload\",\r\n ]\r\n\r\n def build_config(self):\r\n return {\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n \"database_id\": {\r\n \"display_name\": \"Database ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the Notion database to query.\",\r\n },\r\n \"query_payload\": {\r\n \"display_name\": \"Database query\",\r\n \"field_type\": \"str\",\r\n \"info\": \"A JSON string containing the filters that will be used for querying the database. EG: {'filter': {'property': 'Status', 'status': {'equals': 'In progress'}}}\",\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n notion_secret: str,\r\n database_id: str,\r\n query_payload: str = \"{}\",\r\n ) -> List[Record]:\r\n try:\r\n query_data = json.loads(query_payload)\r\n filter_obj = query_data.get(\"filter\")\r\n sorts = query_data.get(\"sorts\", [])\r\n\r\n url = f\"https://api.notion.com/v1/databases/{database_id}/query\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Content-Type\": \"application/json\",\r\n \"Notion-Version\": \"2022-06-28\",\r\n }\r\n\r\n data = {\r\n \"sorts\": sorts,\r\n }\r\n\r\n if filter_obj:\r\n data[\"filter\"] = filter_obj\r\n\r\n response = requests.post(url, headers=headers, json=data)\r\n response.raise_for_status()\r\n\r\n results = response.json()\r\n records = []\r\n combined_text = f\"Pages found: {len(results['results'])}\\n\\n\"\r\n for page in results['results']:\r\n page_data = {\r\n 'id': page['id'],\r\n 'url': page['url'],\r\n 'created_time': page['created_time'],\r\n 'last_edited_time': page['last_edited_time'],\r\n 'properties': page['properties'],\r\n }\r\n\r\n text = (\r\n f\"id: {page['id']}\\n\"\r\n f\"url: {page['url']}\\n\"\r\n f\"created_time: {page['created_time']}\\n\"\r\n f\"last_edited_time: {page['last_edited_time']}\\n\"\r\n f\"properties: {json.dumps(page['properties'], indent=2)}\\n\\n\"\r\n )\r\n\r\n combined_text += text\r\n records.append(Record(text=text, data=page_data))\r\n \r\n self.status = combined_text.strip()\r\n return records\r\n\r\n except Exception as e:\r\n self.status = f\"An error occurred: {str(e)}\"\r\n return [Record(text=self.status, data=[])]","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"database_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"database_id","display_name":"Database ID","advanced":false,"dynamic":false,"info":"The ID of the Notion database to query.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":"NOTION_NMSTX_DB_ID"},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"query_payload":{"type":"str","required":false,"placeholder":"","list":false,"show":true,"multiline":false,"value":{},"fileTypes":[],"file_path":"","password":false,"name":"query_payload","display_name":"Database query","advanced":false,"dynamic":false,"info":"A JSON string containing the filters that will be used for querying the database. EG: {'filter': {'property': 'Status', 'status': {'equals': 'In progress'}}}","load_from_db":false,"title_case":false,"input_types":["Text"]},"_type":"CustomComponent"},"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":["Record"],"display_name":"List Pages [Notion] ","documentation":"https://docs.langflow.org/integrations/notion/list-pages","custom_fields":{"notion_secret":null,"database_id":null,"query_payload":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":["notion_secret","database_id","query_payload"],"beta":false},"id":"CustomComponent-Pn52w","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 [Notion] "},"selected":false,"width":384,"height":517,"positionAbsolute":{"x":-3070.9222948695096,"y":-472.4537855763852},"dragging":false},{"id":"CustomComponent-I8Dec","type":"genericNode","position":{"x":-2256.686402636563,"y":-963.4541117792749},"data":{"type":"CustomComponent","node":{"template":{"block_id":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":false,"name":"block_id","display_name":"Page/Block ID","advanced":false,"dynamic":false,"info":"The ID of the page/block to add the content.","load_from_db":false,"title_case":false,"input_types":["Text"]},"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import json\r\nfrom typing import List, Dict, Any\r\nfrom markdown import markdown\r\nfrom bs4 import BeautifulSoup\r\nimport requests\r\n\r\nfrom langflow import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\nclass AddContentToPage(CustomComponent):\r\n display_name = \"Add Content to Page [Notion]\"\r\n description = \"Convert markdown text to Notion blocks and append them to a Notion page.\"\r\n documentation: str = \"https://developers.notion.com/reference/patch-block-children\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n def build_config(self):\r\n return {\r\n \"markdown_text\": {\r\n \"display_name\": \"Markdown Text\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The markdown text to convert to Notion blocks.\",\r\n \"multiline\": True,\r\n },\r\n \"block_id\": {\r\n \"display_name\": \"Page/Block ID\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The ID of the page/block to add the content.\",\r\n },\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n }\r\n\r\n def build(self, markdown_text: str, block_id: str, notion_secret: str) -> Record:\r\n html_text = markdown(markdown_text)\r\n soup = BeautifulSoup(html_text, 'html.parser')\r\n blocks = self.process_node(soup)\r\n\r\n url = f\"https://api.notion.com/v1/blocks/{block_id}/children\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Content-Type\": \"application/json\",\r\n \"Notion-Version\": \"2022-06-28\",\r\n }\r\n\r\n data = {\r\n \"children\": blocks,\r\n }\r\n\r\n response = requests.patch(url, headers=headers, json=data)\r\n self.status = str(response.json())\r\n response.raise_for_status()\r\n\r\n result = response.json()\r\n self.status = f\"Appended {len(blocks)} blocks to page with ID: {block_id}\"\r\n return Record(data=result, text=json.dumps(result))\r\n\r\n def process_node(self, node):\r\n blocks = []\r\n if isinstance(node, str):\r\n text = node.strip()\r\n if text:\r\n if text.startswith('#'):\r\n heading_level = text.count('#', 0, 6)\r\n heading_text = text[heading_level:].strip()\r\n if heading_level == 1:\r\n blocks.append(self.create_block('heading_1', heading_text))\r\n elif heading_level == 2:\r\n blocks.append(self.create_block('heading_2', heading_text))\r\n elif heading_level == 3:\r\n blocks.append(self.create_block('heading_3', heading_text))\r\n else:\r\n blocks.append(self.create_block('paragraph', text))\r\n elif node.name == 'h1':\r\n blocks.append(self.create_block('heading_1', node.get_text(strip=True)))\r\n elif node.name == 'h2':\r\n blocks.append(self.create_block('heading_2', node.get_text(strip=True)))\r\n elif node.name == 'h3':\r\n blocks.append(self.create_block('heading_3', node.get_text(strip=True)))\r\n elif node.name == 'p':\r\n code_node = node.find('code')\r\n if code_node:\r\n code_text = code_node.get_text()\r\n language, code = self.extract_language_and_code(code_text)\r\n blocks.append(self.create_block('code', code, language=language))\r\n elif self.is_table(str(node)):\r\n blocks.extend(self.process_table(node))\r\n else:\r\n blocks.append(self.create_block('paragraph', node.get_text(strip=True)))\r\n elif node.name == 'ul':\r\n blocks.extend(self.process_list(node, 'bulleted_list_item'))\r\n elif node.name == 'ol':\r\n blocks.extend(self.process_list(node, 'numbered_list_item'))\r\n elif node.name == 'blockquote':\r\n blocks.append(self.create_block('quote', node.get_text(strip=True)))\r\n elif node.name == 'hr':\r\n blocks.append(self.create_block('divider', ''))\r\n elif node.name == 'img':\r\n blocks.append(self.create_block('image', '', image_url=node.get('src')))\r\n elif node.name == 'a':\r\n blocks.append(self.create_block('bookmark', node.get_text(strip=True), link_url=node.get('href')))\r\n elif node.name == 'table':\r\n blocks.extend(self.process_table(node))\r\n\r\n for child in node.children:\r\n if isinstance(child, str):\r\n continue\r\n blocks.extend(self.process_node(child))\r\n\r\n return blocks\r\n\r\n def extract_language_and_code(self, code_text):\r\n lines = code_text.split('\\n')\r\n language = lines[0].strip()\r\n code = '\\n'.join(lines[1:]).strip()\r\n return language, code\r\n\r\n def is_code_block(self, text):\r\n return text.startswith('```')\r\n\r\n def extract_code_block(self, text):\r\n lines = text.split('\\n')\r\n language = lines[0].strip('`').strip()\r\n code = '\\n'.join(lines[1:]).strip('`').strip()\r\n return language, code\r\n \r\n def is_table(self, text):\r\n rows = text.split('\\n')\r\n if len(rows) < 2:\r\n return False\r\n\r\n has_separator = False\r\n for i, row in enumerate(rows):\r\n if '|' in row:\r\n cells = [cell.strip() for cell in row.split('|')]\r\n cells = [cell for cell in cells if cell] # Remove empty cells\r\n if i == 1 and all(set(cell) <= set('-|') for cell in cells):\r\n has_separator = True\r\n elif not cells:\r\n return False\r\n\r\n return has_separator and len(rows) >= 3\r\n\r\n def process_list(self, node, list_type):\r\n blocks = []\r\n for item in node.find_all('li'):\r\n item_text = item.get_text(strip=True)\r\n checked = item_text.startswith('[x]')\r\n is_checklist = item_text.startswith('[ ]') or checked\r\n\r\n if is_checklist:\r\n item_text = item_text.replace('[x]', '').replace('[ ]', '').strip()\r\n blocks.append(self.create_block('to_do', item_text, checked=checked))\r\n else:\r\n blocks.append(self.create_block(list_type, item_text))\r\n return blocks\r\n\r\n def process_table(self, node):\r\n blocks = []\r\n header_row = node.find('thead').find('tr') if node.find('thead') else None\r\n body_rows = node.find('tbody').find_all('tr') if node.find('tbody') else []\r\n\r\n if header_row or body_rows:\r\n table_width = max(len(header_row.find_all(['th', 'td'])) if header_row else 0,\r\n max(len(row.find_all(['th', 'td'])) for row in body_rows))\r\n\r\n table_block = self.create_block('table', '', table_width=table_width, has_column_header=bool(header_row))\r\n blocks.append(table_block)\r\n\r\n if header_row:\r\n header_cells = [cell.get_text(strip=True) for cell in header_row.find_all(['th', 'td'])]\r\n header_row_block = self.create_block('table_row', header_cells)\r\n blocks.append(header_row_block)\r\n\r\n for row in body_rows:\r\n cells = [cell.get_text(strip=True) for cell in row.find_all(['th', 'td'])]\r\n row_block = self.create_block('table_row', cells)\r\n blocks.append(row_block)\r\n\r\n return blocks\r\n \r\n def create_block(self, block_type: str, content: str, **kwargs) -> Dict[str, Any]:\r\n block = {\r\n \"object\": \"block\",\r\n \"type\": block_type,\r\n block_type: {},\r\n }\r\n\r\n if block_type in [\"paragraph\", \"heading_1\", \"heading_2\", \"heading_3\", \"bulleted_list_item\", \"numbered_list_item\", \"quote\"]:\r\n block[block_type][\"rich_text\"] = [\r\n {\r\n \"type\": \"text\",\r\n \"text\": {\r\n \"content\": content,\r\n },\r\n }\r\n ]\r\n elif block_type == 'to_do':\r\n block[block_type][\"rich_text\"] = [\r\n {\r\n \"type\": \"text\",\r\n \"text\": {\r\n \"content\": content,\r\n },\r\n }\r\n ]\r\n block[block_type]['checked'] = kwargs.get('checked', False)\r\n elif block_type == 'code':\r\n block[block_type]['rich_text'] = [\r\n {\r\n \"type\": \"text\",\r\n \"text\": {\r\n \"content\": content,\r\n },\r\n }\r\n ]\r\n block[block_type]['language'] = kwargs.get('language', 'plain text')\r\n elif block_type == 'image':\r\n block[block_type] = {\r\n \"type\": \"external\",\r\n \"external\": {\r\n \"url\": kwargs.get('image_url', '')\r\n }\r\n }\r\n elif block_type == 'divider':\r\n pass\r\n elif block_type == 'bookmark':\r\n block[block_type]['url'] = kwargs.get('link_url', '')\r\n elif block_type == 'table':\r\n block[block_type]['table_width'] = kwargs.get('table_width', 0)\r\n block[block_type]['has_column_header'] = kwargs.get('has_column_header', False)\r\n block[block_type]['has_row_header'] = kwargs.get('has_row_header', False)\r\n elif block_type == 'table_row':\r\n block[block_type]['cells'] = [[{'type': 'text', 'text': {'content': cell}} for cell in content]]\r\n\r\n return block","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"markdown_text":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"fileTypes":[],"file_path":"","password":false,"name":"markdown_text","display_name":"Markdown Text","advanced":false,"dynamic":false,"info":"The markdown text to convert to Notion blocks.","load_from_db":false,"title_case":false,"input_types":["Text"],"value":"# Heading 1\n\n## Heading 2\n\n### Heading 3\n\nThis is a regular paragraph.\n\nHere's another paragraph with an image:\n\n\n## Checklist\n- [x] Completed task\n- [ ] Incomplete task\n- [x] Another completed task\n\n## Numbered List\n1. First item\n2. Second item\n3. Third item\n\n## Bulleted List\n- Item 1\n- Item 2\n- Item 3\n\n## Code Block\n```python\ndef hello_world():\n print(\"Hello, World!\")\n```\n\n## Quote\n> This is a blockquote.\n> It can span multiple lines.\n\n## Horizontal Rule\n---\n\n\n## Link\n[Notion API Documentation](https://developers.notion.com)\n\n"},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"_type":"CustomComponent"},"description":"Convert markdown text to Notion blocks and append them to a Notion page.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"Add Content to Page [Notion] ","documentation":"https://developers.notion.com/reference/patch-block-children","custom_fields":{"markdown_text":null,"block_id":null,"notion_secret":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":[],"beta":false,"official":false},"id":"CustomComponent-I8Dec"},"selected":false,"width":384,"height":497,"positionAbsolute":{"x":-2256.686402636563,"y":-963.4541117792749},"dragging":false},{"id":"CustomComponent-ZcsA9","type":"genericNode","position":{"x":-3488.029350341937,"y":-965.3756250644985},"data":{"type":"CustomComponent","node":{"template":{"code":{"type":"code","required":true,"placeholder":"","list":false,"show":true,"multiline":true,"value":"import requests\r\nfrom typing import Dict, Any, List\r\nfrom langflow.custom import CustomComponent\r\nfrom langflow.schema import Record\r\n\r\nclass NotionSearch(CustomComponent):\r\n display_name = \"Search Notion\"\r\n description = (\r\n \"Searches all pages and databases that have been shared with an integration.\"\r\n )\r\n documentation: str = \"https://docs.langflow.org/integrations/notion/search\"\r\n icon = \"NotionDirectoryLoader\"\r\n\r\n field_order = [\r\n \"notion_secret\",\r\n \"query\",\r\n \"filter_value\",\r\n \"sort_direction\",\r\n ]\r\n\r\n def build_config(self):\r\n return {\r\n \"notion_secret\": {\r\n \"display_name\": \"Notion Secret\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The Notion integration token.\",\r\n \"password\": True,\r\n },\r\n \"query\": {\r\n \"display_name\": \"Search Query\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The text that the API compares page and database titles against.\",\r\n },\r\n \"filter_value\": {\r\n \"display_name\": \"Filter Type\",\r\n \"field_type\": \"str\",\r\n \"info\": \"Limits the results to either only pages or only databases.\",\r\n \"options\": [\"page\", \"database\"],\r\n \"default_value\": \"page\",\r\n },\r\n \"sort_direction\": {\r\n \"display_name\": \"Sort Direction\",\r\n \"field_type\": \"str\",\r\n \"info\": \"The direction to sort the results.\",\r\n \"options\": [\"ascending\", \"descending\"],\r\n \"default_value\": \"descending\",\r\n },\r\n }\r\n\r\n def build(\r\n self,\r\n notion_secret: str,\r\n query: str = \"\",\r\n filter_value: str = \"page\",\r\n sort_direction: str = \"descending\",\r\n ) -> List[Record]:\r\n try:\r\n url = \"https://api.notion.com/v1/search\"\r\n headers = {\r\n \"Authorization\": f\"Bearer {notion_secret}\",\r\n \"Content-Type\": \"application/json\",\r\n \"Notion-Version\": \"2022-06-28\",\r\n }\r\n\r\n data = {\r\n \"query\": query,\r\n \"filter\": {\r\n \"value\": filter_value,\r\n \"property\": \"object\"\r\n },\r\n \"sort\":{\r\n \"direction\": sort_direction,\r\n \"timestamp\": \"last_edited_time\"\r\n }\r\n }\r\n\r\n response = requests.post(url, headers=headers, json=data)\r\n response.raise_for_status()\r\n\r\n results = response.json()\r\n records = []\r\n combined_text = f\"Results found: {len(results['results'])}\\n\\n\"\r\n for result in results['results']:\r\n result_data = {\r\n 'id': result['id'],\r\n 'type': result['object'],\r\n 'last_edited_time': result['last_edited_time'],\r\n }\r\n \r\n if result['object'] == 'page':\r\n result_data['title_or_url'] = result['url']\r\n text = f\"id: {result['id']}\\ntitle_or_url: {result['url']}\\n\"\r\n elif result['object'] == 'database':\r\n if 'title' in result and isinstance(result['title'], list) and len(result['title']) > 0:\r\n result_data['title_or_url'] = result['title'][0]['plain_text']\r\n text = f\"id: {result['id']}\\ntitle_or_url: {result['title'][0]['plain_text']}\\n\"\r\n else:\r\n result_data['title_or_url'] = \"N/A\"\r\n text = f\"id: {result['id']}\\ntitle_or_url: N/A\\n\"\r\n\r\n text += f\"type: {result['object']}\\nlast_edited_time: {result['last_edited_time']}\\n\\n\"\r\n combined_text += text\r\n records.append(Record(text=text, data=result_data))\r\n \r\n self.status = combined_text\r\n return records\r\n\r\n except Exception as e:\r\n self.status = f\"An error occurred: {str(e)}\"\r\n return [Record(text=self.status, data=[])]","fileTypes":[],"file_path":"","password":false,"name":"code","advanced":true,"dynamic":true,"info":"","load_from_db":false,"title_case":false},"filter_value":{"type":"str","required":false,"placeholder":"","list":true,"show":true,"multiline":false,"value":"database","fileTypes":[],"file_path":"","password":false,"options":["page","database"],"name":"filter_value","display_name":"Filter Type","advanced":false,"dynamic":false,"info":"Limits the results to either only pages or only databases.","load_from_db":false,"title_case":false,"input_types":["Text"]},"notion_secret":{"type":"str","required":true,"placeholder":"","list":false,"show":true,"multiline":false,"fileTypes":[],"file_path":"","password":true,"name":"notion_secret","display_name":"Notion Secret","advanced":false,"dynamic":false,"info":"The Notion integration token.","load_from_db":true,"title_case":false,"input_types":["Text"],"value":""},"query":{"type":"str","required":false,"placeholder":"","list":false,"show":true,"multiline":false,"value":"","fileTypes":[],"file_path":"","password":false,"name":"query","display_name":"Search Query","advanced":false,"dynamic":false,"info":"The text that the API compares page and database titles against.","load_from_db":false,"title_case":false,"input_types":["Text"]},"sort_direction":{"type":"str","required":false,"placeholder":"","list":true,"show":true,"multiline":false,"value":"descending","fileTypes":[],"file_path":"","password":false,"options":["ascending","descending"],"name":"sort_direction","display_name":"Sort Direction","advanced":false,"dynamic":false,"info":"The direction to sort the results.","load_from_db":false,"title_case":false,"input_types":["Text"]},"_type":"CustomComponent"},"description":"Searches all pages and databases that have been shared with an integration.","icon":"NotionDirectoryLoader","base_classes":["Record"],"display_name":"Search [Notion]","documentation":"https://docs.langflow.org/integrations/notion/search","custom_fields":{"notion_secret":null,"query":null,"filter_value":null,"sort_direction":null},"output_types":["Record"],"field_formatters":{},"frozen":false,"field_order":["notion_secret","query","filter_value","sort_direction"],"beta":false},"id":"CustomComponent-ZcsA9","description":"Searches all pages and databases that have been shared with an integration.","display_name":"Search [Notion]"},"selected":false,"width":384,"height":591,"positionAbsolute":{"x":-3488.029350341937,"y":-965.3756250644985},"dragging":false}],"edges":[],"viewport":{"x":2623.378922967084,"y":696.8541079344027,"zoom":0.5981384177708997}},"description":"A Bundle containing Notion components for Page and Database manipulation. You can list pages, users databases, update properties, create new pages and add content to Notion Pages.","name":"Notion - Components","last_tested_version":"1.0.0a36","is_component":false}
\ No newline at end of file
diff --git a/poetry.lock b/poetry.lock
index ee02dc69b..d8875763d 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1310,63 +1310,63 @@ files = [
[[package]]
name = "coverage"
-version = "7.5.2"
+version = "7.5.3"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "coverage-7.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:554c7327bf0fd688050348e22db7c8e163fb7219f3ecdd4732d7ed606b417263"},
- {file = "coverage-7.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d0305e02e40c7cfea5d08d6368576537a74c0eea62b77633179748d3519d6705"},
- {file = "coverage-7.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:829fb55ad437d757c70d5b1c51cfda9377f31506a0a3f3ac282bc6a387d6a5f1"},
- {file = "coverage-7.5.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:894b1acded706f1407a662d08e026bfd0ff1e59e9bd32062fea9d862564cfb65"},
- {file = "coverage-7.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe76d6dee5e4febefa83998b17926df3a04e5089e3d2b1688c74a9157798d7a2"},
- {file = "coverage-7.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c7ebf2a37e4f5fea3c1a11e1f47cea7d75d0f2d8ef69635ddbd5c927083211fc"},
- {file = "coverage-7.5.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20e611fc36e1a0fc7bbf957ef9c635c8807d71fbe5643e51b2769b3cc0fb0b51"},
- {file = "coverage-7.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7c5c5b7ae2763533152880d5b5b451acbc1089ade2336b710a24b2b0f5239d20"},
- {file = "coverage-7.5.2-cp310-cp310-win32.whl", hash = "sha256:1e4225990a87df898e40ca31c9e830c15c2c53b1d33df592bc8ef314d71f0281"},
- {file = "coverage-7.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:976cd92d9420e6e2aa6ce6a9d61f2b490e07cb468968adf371546b33b829284b"},
- {file = "coverage-7.5.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5997d418c219dcd4dcba64e50671cca849aaf0dac3d7a2eeeb7d651a5bd735b8"},
- {file = "coverage-7.5.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ec27e93bbf5976f0465e8936f02eb5add99bbe4e4e7b233607e4d7622912d68d"},
- {file = "coverage-7.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f11f98753800eb1ec872562a398081f6695f91cd01ce39819e36621003ec52a"},
- {file = "coverage-7.5.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e34680049eecb30b6498784c9637c1c74277dcb1db75649a152f8004fbd6646"},
- {file = "coverage-7.5.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e12536446ad4527ac8ed91d8a607813085683bcce27af69e3b31cd72b3c5960"},
- {file = "coverage-7.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3d3f7744b8a8079d69af69d512e5abed4fb473057625588ce126088e50d05493"},
- {file = "coverage-7.5.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:431a3917e32223fcdb90b79fe60185864a9109631ebc05f6c5aa03781a00b513"},
- {file = "coverage-7.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a7c6574225f34ce45466f04751d957b5c5e6b69fca9351db017c9249786172ce"},
- {file = "coverage-7.5.2-cp311-cp311-win32.whl", hash = "sha256:2b144d142ec9987276aeff1326edbc0df8ba4afbd7232f0ca10ad57a115e95b6"},
- {file = "coverage-7.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:900532713115ac58bc3491b9d2b52704a05ed408ba0918d57fd72c94bc47fba1"},
- {file = "coverage-7.5.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9a42970ce74c88bdf144df11c52c5cf4ad610d860de87c0883385a1c9d9fa4ab"},
- {file = "coverage-7.5.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:26716a1118c6ce2188283b4b60a898c3be29b480acbd0a91446ced4fe4e780d8"},
- {file = "coverage-7.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60b66b0363c5a2a79fba3d1cd7430c25bbd92c923d031cae906bdcb6e054d9a2"},
- {file = "coverage-7.5.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5d22eba19273b2069e4efeff88c897a26bdc64633cbe0357a198f92dca94268"},
- {file = "coverage-7.5.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3bb5b92a0ab3d22dfdbfe845e2fef92717b067bdf41a5b68c7e3e857c0cff1a4"},
- {file = "coverage-7.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1aef719b6559b521ae913ddeb38f5048c6d1a3d366865e8b320270b7bc4693c2"},
- {file = "coverage-7.5.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8809c0ea0e8454f756e3bd5c36d04dddf222989216788a25bfd6724bfcee342c"},
- {file = "coverage-7.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:1acc2e2ef098a1d4bf535758085f508097316d738101a97c3f996bccba963ea5"},
- {file = "coverage-7.5.2-cp312-cp312-win32.whl", hash = "sha256:97de509043d3f0f2b2cd171bdccf408f175c7f7a99d36d566b1ae4dd84107985"},
- {file = "coverage-7.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:8941e35a0e991a7a20a1fa3e3182f82abe357211f2c335a9e6007067c3392fcf"},
- {file = "coverage-7.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5662bf0f6fb6757f5c2d6279c541a5af55a39772c2362ed0920b27e3ce0e21f7"},
- {file = "coverage-7.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d9c62cff2ffb4c2a95328488fd7aa96a7a4b34873150650fe76b19c08c9c792"},
- {file = "coverage-7.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74eeaa13e8200ad72fca9c5f37395fb310915cec6f1682b21375e84fd9770e84"},
- {file = "coverage-7.5.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f29bf497d51a5077994b265e976d78b09d9d0dff6ca5763dbb4804534a5d380"},
- {file = "coverage-7.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f96aa94739593ae0707eda9813ce363a0a0374a810ae0eced383340fc4a1f73"},
- {file = "coverage-7.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:51b6cee539168a912b4b3b040e4042b9e2c9a7ad9c8546c09e4eaeff3eacba6b"},
- {file = "coverage-7.5.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:59a75e6aa5c25b50b5a1499f9718f2edff54257f545718c4fb100f48d570ead4"},
- {file = "coverage-7.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:29da75ce20cb0a26d60e22658dd3230713c6c05a3465dd8ad040ffc991aea318"},
- {file = "coverage-7.5.2-cp38-cp38-win32.whl", hash = "sha256:23f2f16958b16152b43a39a5ecf4705757ddd284b3b17a77da3a62aef9c057ef"},
- {file = "coverage-7.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:9e41c94035e5cdb362beed681b58a707e8dc29ea446ea1713d92afeded9d1ddd"},
- {file = "coverage-7.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:06d96b9b19bbe7f049c2be3c4f9e06737ec6d8ef8933c7c3a4c557ef07936e46"},
- {file = "coverage-7.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:878243e1206828908a6b4a9ca7b1aa8bee9eb129bf7186fc381d2646f4524ce9"},
- {file = "coverage-7.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:482df956b055d3009d10fce81af6ffab28215d7ed6ad4a15e5c8e67cb7c5251c"},
- {file = "coverage-7.5.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a35c97af60a5492e9e89f8b7153fe24eadfd61cb3a2fb600df1a25b5dab34b7e"},
- {file = "coverage-7.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24bb4c7859a3f757a116521d4d3a8a82befad56ea1bdacd17d6aafd113b0071e"},
- {file = "coverage-7.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e1046aab24c48c694f0793f669ac49ea68acde6a0798ac5388abe0a5615b5ec8"},
- {file = "coverage-7.5.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:448ec61ea9ea7916d5579939362509145caaecf03161f6f13e366aebb692a631"},
- {file = "coverage-7.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4a00bd5ba8f1a4114720bef283cf31583d6cb1c510ce890a6da6c4268f0070b7"},
- {file = "coverage-7.5.2-cp39-cp39-win32.whl", hash = "sha256:9f805481d5eff2a96bac4da1570ef662bf970f9a16580dc2c169c8c3183fa02b"},
- {file = "coverage-7.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:2c79f058e7bec26b5295d53b8c39ecb623448c74ccc8378631f5cb5c16a7e02c"},
- {file = "coverage-7.5.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:40dbb8e7727560fe8ab65efcddfec1ae25f30ef02e2f2e5d78cfb52a66781ec5"},
- {file = "coverage-7.5.2.tar.gz", hash = "sha256:13017a63b0e499c59b5ba94a8542fb62864ba3016127d1e4ef30d354fc2b00e9"},
+ {file = "coverage-7.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a6519d917abb15e12380406d721e37613e2a67d166f9fb7e5a8ce0375744cd45"},
+ {file = "coverage-7.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aea7da970f1feccf48be7335f8b2ca64baf9b589d79e05b9397a06696ce1a1ec"},
+ {file = "coverage-7.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:923b7b1c717bd0f0f92d862d1ff51d9b2b55dbbd133e05680204465f454bb286"},
+ {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62bda40da1e68898186f274f832ef3e759ce929da9a9fd9fcf265956de269dbc"},
+ {file = "coverage-7.5.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8b7339180d00de83e930358223c617cc343dd08e1aa5ec7b06c3a121aec4e1d"},
+ {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:25a5caf742c6195e08002d3b6c2dd6947e50efc5fc2c2205f61ecb47592d2d83"},
+ {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:05ac5f60faa0c704c0f7e6a5cbfd6f02101ed05e0aee4d2822637a9e672c998d"},
+ {file = "coverage-7.5.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:239a4e75e09c2b12ea478d28815acf83334d32e722e7433471fbf641c606344c"},
+ {file = "coverage-7.5.3-cp310-cp310-win32.whl", hash = "sha256:a5812840d1d00eafae6585aba38021f90a705a25b8216ec7f66aebe5b619fb84"},
+ {file = "coverage-7.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:33ca90a0eb29225f195e30684ba4a6db05dbef03c2ccd50b9077714c48153cac"},
+ {file = "coverage-7.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81bc26d609bf0fbc622c7122ba6307993c83c795d2d6f6f6fd8c000a770d974"},
+ {file = "coverage-7.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7cec2af81f9e7569280822be68bd57e51b86d42e59ea30d10ebdbb22d2cb7232"},
+ {file = "coverage-7.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55f689f846661e3f26efa535071775d0483388a1ccfab899df72924805e9e7cd"},
+ {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50084d3516aa263791198913a17354bd1dc627d3c1639209640b9cac3fef5807"},
+ {file = "coverage-7.5.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341dd8f61c26337c37988345ca5c8ccabeff33093a26953a1ac72e7d0103c4fb"},
+ {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ab0b028165eea880af12f66086694768f2c3139b2c31ad5e032c8edbafca6ffc"},
+ {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5bc5a8c87714b0c67cfeb4c7caa82b2d71e8864d1a46aa990b5588fa953673b8"},
+ {file = "coverage-7.5.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:38a3b98dae8a7c9057bd91fbf3415c05e700a5114c5f1b5b0ea5f8f429ba6614"},
+ {file = "coverage-7.5.3-cp311-cp311-win32.whl", hash = "sha256:fcf7d1d6f5da887ca04302db8e0e0cf56ce9a5e05f202720e49b3e8157ddb9a9"},
+ {file = "coverage-7.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:8c836309931839cca658a78a888dab9676b5c988d0dd34ca247f5f3e679f4e7a"},
+ {file = "coverage-7.5.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:296a7d9bbc598e8744c00f7a6cecf1da9b30ae9ad51c566291ff1314e6cbbed8"},
+ {file = "coverage-7.5.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:34d6d21d8795a97b14d503dcaf74226ae51eb1f2bd41015d3ef332a24d0a17b3"},
+ {file = "coverage-7.5.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e317953bb4c074c06c798a11dbdd2cf9979dbcaa8ccc0fa4701d80042d4ebf1"},
+ {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:705f3d7c2b098c40f5b81790a5fedb274113373d4d1a69e65f8b68b0cc26f6db"},
+ {file = "coverage-7.5.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1196e13c45e327d6cd0b6e471530a1882f1017eb83c6229fc613cd1a11b53cd"},
+ {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:015eddc5ccd5364dcb902eaecf9515636806fa1e0d5bef5769d06d0f31b54523"},
+ {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:fd27d8b49e574e50caa65196d908f80e4dff64d7e592d0c59788b45aad7e8b35"},
+ {file = "coverage-7.5.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:33fc65740267222fc02975c061eb7167185fef4cc8f2770267ee8bf7d6a42f84"},
+ {file = "coverage-7.5.3-cp312-cp312-win32.whl", hash = "sha256:7b2a19e13dfb5c8e145c7a6ea959485ee8e2204699903c88c7d25283584bfc08"},
+ {file = "coverage-7.5.3-cp312-cp312-win_amd64.whl", hash = "sha256:0bbddc54bbacfc09b3edaec644d4ac90c08ee8ed4844b0f86227dcda2d428fcb"},
+ {file = "coverage-7.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f78300789a708ac1f17e134593f577407d52d0417305435b134805c4fb135adb"},
+ {file = "coverage-7.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b368e1aee1b9b75757942d44d7598dcd22a9dbb126affcbba82d15917f0cc155"},
+ {file = "coverage-7.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f836c174c3a7f639bded48ec913f348c4761cbf49de4a20a956d3431a7c9cb24"},
+ {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:244f509f126dc71369393ce5fea17c0592c40ee44e607b6d855e9c4ac57aac98"},
+ {file = "coverage-7.5.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4c2872b3c91f9baa836147ca33650dc5c172e9273c808c3c3199c75490e709d"},
+ {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dd4b3355b01273a56b20c219e74e7549e14370b31a4ffe42706a8cda91f19f6d"},
+ {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f542287b1489c7a860d43a7d8883e27ca62ab84ca53c965d11dac1d3a1fab7ce"},
+ {file = "coverage-7.5.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:75e3f4e86804023e991096b29e147e635f5e2568f77883a1e6eed74512659ab0"},
+ {file = "coverage-7.5.3-cp38-cp38-win32.whl", hash = "sha256:c59d2ad092dc0551d9f79d9d44d005c945ba95832a6798f98f9216ede3d5f485"},
+ {file = "coverage-7.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:fa21a04112c59ad54f69d80e376f7f9d0f5f9123ab87ecd18fbb9ec3a2beed56"},
+ {file = "coverage-7.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5102a92855d518b0996eb197772f5ac2a527c0ec617124ad5242a3af5e25f85"},
+ {file = "coverage-7.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d1da0a2e3b37b745a2b2a678a4c796462cf753aebf94edcc87dcc6b8641eae31"},
+ {file = "coverage-7.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8383a6c8cefba1b7cecc0149415046b6fc38836295bc4c84e820872eb5478b3d"},
+ {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9aad68c3f2566dfae84bf46295a79e79d904e1c21ccfc66de88cd446f8686341"},
+ {file = "coverage-7.5.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e079c9ec772fedbade9d7ebc36202a1d9ef7291bc9b3a024ca395c4d52853d7"},
+ {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bde997cac85fcac227b27d4fb2c7608a2c5f6558469b0eb704c5726ae49e1c52"},
+ {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:990fb20b32990b2ce2c5f974c3e738c9358b2735bc05075d50a6f36721b8f303"},
+ {file = "coverage-7.5.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3d5a67f0da401e105753d474369ab034c7bae51a4c31c77d94030d59e41df5bd"},
+ {file = "coverage-7.5.3-cp39-cp39-win32.whl", hash = "sha256:e08c470c2eb01977d221fd87495b44867a56d4d594f43739a8028f8646a51e0d"},
+ {file = "coverage-7.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:1d2a830ade66d3563bb61d1e3c77c8def97b30ed91e166c67d0632c018f380f0"},
+ {file = "coverage-7.5.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:3538d8fb1ee9bdd2e2692b3b18c22bb1c19ffbefd06880f5ac496e42d7bb3884"},
+ {file = "coverage-7.5.3.tar.gz", hash = "sha256:04aefca5190d1dc7a53a4c1a5a7f8568811306d7a8ee231c42fb69215571944f"},
]
[package.dependencies]
@@ -1807,13 +1807,13 @@ gmpy2 = ["gmpy2"]
[[package]]
name = "elastic-transport"
-version = "8.13.0"
+version = "8.13.1"
description = "Transport classes and utilities shared among Python Elastic client libraries"
optional = false
python-versions = ">=3.7"
files = [
- {file = "elastic-transport-8.13.0.tar.gz", hash = "sha256:2410ec1ff51221e8b3a01c0afa9f0d0498e1386a269283801f5c12f98e42dc45"},
- {file = "elastic_transport-8.13.0-py3-none-any.whl", hash = "sha256:aec890afdddd057762b27ff3553b0be8fa4673ec1a4fd922dfbd00325874bb3d"},
+ {file = "elastic_transport-8.13.1-py3-none-any.whl", hash = "sha256:5d4bb6b8e9d74a9c16de274e91a5caf65a3a8d12876f1e99152975e15b2746fe"},
+ {file = "elastic_transport-8.13.1.tar.gz", hash = "sha256:16339d392b4bbe86ad00b4bdeecff10edf516d32bc6c16053846625f2c6ea250"},
]
[package.dependencies]
@@ -2539,13 +2539,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
-version = "2.130.0"
+version = "2.131.0"
description = "Google API Client Library for Python"
optional = false
python-versions = ">=3.7"
files = [
- {file = "google-api-python-client-2.130.0.tar.gz", hash = "sha256:2bba3122b82a649c677b8a694b8e2bbf2a5fbf3420265caf3343bb88e2e9f0ae"},
- {file = "google_api_python_client-2.130.0-py2.py3-none-any.whl", hash = "sha256:7d45a28d738628715944a9c9d73e8696e7e03ac50b7de87f5e3035cefa94ed3a"},
+ {file = "google-api-python-client-2.131.0.tar.gz", hash = "sha256:1c03e24af62238a8817ecc24e9d4c32ddd4cb1f323b08413652d9a9a592fc00d"},
+ {file = "google_api_python_client-2.131.0-py2.py3-none-any.whl", hash = "sha256:e325409bdcef4604d505d9246ce7199960a010a0569ac503b9f319db8dbdc217"},
]
[package.dependencies]
@@ -4323,7 +4323,7 @@ types-requests = ">=2.31.0.2,<3.0.0.0"
[[package]]
name = "langflow-base"
-version = "0.0.49"
+version = "0.0.50"
description = "A Python package with a built-in web application"
optional = false
python-versions = ">=3.10,<3.13"
@@ -4419,13 +4419,13 @@ requests = ">=2,<3"
[[package]]
name = "litellm"
-version = "1.38.10"
+version = "1.38.11"
description = "Library to easily interface with LLM API providers"
optional = false
python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8"
files = [
- {file = "litellm-1.38.10-py3-none-any.whl", hash = "sha256:4d33465eacde566832b9d7aa7677476e61aa7ba4ec26631fb1c8411c87219ed1"},
- {file = "litellm-1.38.10.tar.gz", hash = "sha256:1a0b3088fe4b072f367343a7d7d25e4c5f9990975d9ee7dbf21f3b25ff046bb0"},
+ {file = "litellm-1.38.11-py3-none-any.whl", hash = "sha256:772e0f3b2a78184bbfe221004ad031939b7d76d5be0e5537effdf8afb82e8ac0"},
+ {file = "litellm-1.38.11.tar.gz", hash = "sha256:5c65b707e4779000913c54da144ad93e7ef4ca0f25215ae386fe2cadd41bf744"},
]
[package.dependencies]
@@ -6257,13 +6257,13 @@ twisted = ["twisted"]
[[package]]
name = "prompt-toolkit"
-version = "3.0.43"
+version = "3.0.45"
description = "Library for building powerful interactive command lines in Python"
optional = false
python-versions = ">=3.7.0"
files = [
- {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"},
- {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"},
+ {file = "prompt_toolkit-3.0.45-py3-none-any.whl", hash = "sha256:a29b89160e494e3ea8622b09fa5897610b437884dcdcd054fdc1308883326c2a"},
+ {file = "prompt_toolkit-3.0.45.tar.gz", hash = "sha256:07c60ee4ab7b7e90824b61afa840c8f5aad2d46b3e2e10acc33d8ecc94a49089"},
]
[package.dependencies]
@@ -8343,30 +8343,30 @@ test = ["pylint", "pytest", "pytest-black", "pytest-cov", "pytest-pylint"]
[[package]]
name = "structlog"
-version = "24.1.0"
+version = "24.2.0"
description = "Structured Logging for Python"
optional = false
python-versions = ">=3.8"
files = [
- {file = "structlog-24.1.0-py3-none-any.whl", hash = "sha256:3f6efe7d25fab6e86f277713c218044669906537bb717c1807a09d46bca0714d"},
- {file = "structlog-24.1.0.tar.gz", hash = "sha256:41a09886e4d55df25bdcb9b5c9674bccfab723ff43e0a86a1b7b236be8e57b16"},
+ {file = "structlog-24.2.0-py3-none-any.whl", hash = "sha256:983bd49f70725c5e1e3867096c0c09665918936b3db27341b41d294283d7a48a"},
+ {file = "structlog-24.2.0.tar.gz", hash = "sha256:0e3fe74924a6d8857d3f612739efb94c72a7417d7c7c008d12276bca3b5bf13b"},
]
[package.extras]
-dev = ["structlog[tests,typing]"]
+dev = ["freezegun (>=0.2.8)", "mypy (>=1.4)", "pretend", "pytest (>=6.0)", "pytest-asyncio (>=0.17)", "rich", "simplejson", "twisted"]
docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-mermaid", "sphinxext-opengraph", "twisted"]
tests = ["freezegun (>=0.2.8)", "pretend", "pytest (>=6.0)", "pytest-asyncio (>=0.17)", "simplejson"]
typing = ["mypy (>=1.4)", "rich", "twisted"]
[[package]]
name = "supabase"
-version = "2.4.6"
+version = "2.5.0"
description = "Supabase client for Python."
optional = false
python-versions = "<4.0,>=3.8"
files = [
- {file = "supabase-2.4.6-py3-none-any.whl", hash = "sha256:0bfd6bb33c0e6d6891b55caaf689140f47588b01436fecc336d1d75090c70e8b"},
- {file = "supabase-2.4.6.tar.gz", hash = "sha256:442be0729f5fd9258326ba89859f60bfd8d9218283ed7fd8a62ae81e2f310474"},
+ {file = "supabase-2.5.0-py3-none-any.whl", hash = "sha256:13e5ed9e9377a1a69e70ad18ed7b82997cf13ffcd28173952f7503e4d5067771"},
+ {file = "supabase-2.5.0.tar.gz", hash = "sha256:133dc832dfdd617f2f90ac5b52664df96ac8a9302ac6656ee769dc3f545812f0"},
]
[package.dependencies]
diff --git a/pyproject.toml b/pyproject.toml
index 83834f95e..3c8a4cb07 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow"
-version = "1.0.0a38"
+version = "1.0.0a39"
description = "A Python package with a built-in web application"
authors = ["Langflow
"]
maintainers = [
diff --git a/src/backend/base/langflow/__main__.py b/src/backend/base/langflow/__main__.py
index 4d59b3149..4162629dd 100644
--- a/src/backend/base/langflow/__main__.py
+++ b/src/backend/base/langflow/__main__.py
@@ -77,7 +77,7 @@ def set_var_for_macos_issue():
def run(
host: str = typer.Option("127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"),
workers: int = typer.Option(1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"),
- timeout: int = typer.Option(300, help="Worker timeout in seconds."),
+ timeout: int = typer.Option(300, help="Worker timeout in seconds.", envvar="LANGFLOW_WORKER_TIMEOUT"),
port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
components_path: Optional[Path] = typer.Option(
Path(__file__).parent / "components",
@@ -145,6 +145,10 @@ def run(
if is_port_in_use(port, host):
port = get_free_port(port)
+ settings_service = get_settings_service()
+
+ settings_service.set("worker_timeout", timeout)
+
options = {
"bind": f"{host}:{port}",
"workers": get_number_of_workers(workers),
diff --git a/src/backend/base/langflow/api/v1/endpoints.py b/src/backend/base/langflow/api/v1/endpoints.py
index b47774c8b..006099b15 100644
--- a/src/backend/base/langflow/api/v1/endpoints.py
+++ b/src/backend/base/langflow/api/v1/endpoints.py
@@ -1,5 +1,5 @@
from http import HTTPStatus
-from typing import Annotated, List, Optional, Union
+from typing import TYPE_CHECKING, Annotated, List, Optional, Union
from uuid import UUID
import sqlalchemy as sa
@@ -9,6 +9,7 @@ from sqlmodel import Session, select
from langflow.api.utils import update_frontend_node_with_template_values
from langflow.api.v1.schemas import (
+ ConfigResponse,
CustomComponentRequest,
InputValueRequest,
ProcessResponse,
@@ -31,7 +32,9 @@ from langflow.services.deps import get_session, get_session_service, get_setting
from langflow.services.session.service import SessionService
from langflow.services.task.service import TaskService
-# build router
+if TYPE_CHECKING:
+ from langflow.services.settings.manager import SettingsService
+
router = APIRouter(tags=["Base"])
@@ -440,3 +443,15 @@ async def custom_component_update(
except Exception as exc:
logger.exception(exc)
raise HTTPException(status_code=400, detail=str(exc)) from exc
+
+
+@router.get("/config", response_model=ConfigResponse)
+def get_config():
+ try:
+ from langflow.services.deps import get_settings_service
+
+ settings_service: "SettingsService" = get_settings_service()
+ return settings_service.settings.model_dump()
+ except Exception as exc:
+ logger.exception(exc)
+ raise HTTPException(status_code=500, detail=str(exc)) from exc
diff --git a/src/backend/base/langflow/api/v1/schemas.py b/src/backend/base/langflow/api/v1/schemas.py
index dd0bac9ee..123be10ae 100644
--- a/src/backend/base/langflow/api/v1/schemas.py
+++ b/src/backend/base/langflow/api/v1/schemas.py
@@ -322,3 +322,7 @@ class FlowDataRequest(BaseModel):
nodes: List[dict]
edges: List[dict]
viewport: Optional[dict] = None
+
+
+class ConfigResponse(BaseModel):
+ frontend_timeout: int
diff --git a/src/backend/base/langflow/base/flow_processing/__init__.py b/src/backend/base/langflow/base/flow_processing/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/backend/base/langflow/base/flow_processing/utils.py b/src/backend/base/langflow/base/flow_processing/utils.py
new file mode 100644
index 000000000..4e121f128
--- /dev/null
+++ b/src/backend/base/langflow/base/flow_processing/utils.py
@@ -0,0 +1,67 @@
+from typing import List
+
+from langflow.graph.schema import ResultData, RunOutputs
+from langflow.schema.schema import Record
+
+
+def build_records_from_run_outputs(run_outputs: RunOutputs) -> List[Record]:
+ """
+ Build a list of records from the given RunOutputs.
+
+ Args:
+ run_outputs (RunOutputs): The RunOutputs object containing the output data.
+
+ Returns:
+ List[Record]: A list of records built from the RunOutputs.
+
+ """
+ if not run_outputs:
+ return []
+ records = []
+ for result_data in run_outputs.outputs:
+ if result_data:
+ records.extend(build_records_from_result_data(result_data))
+ return records
+
+
+def build_records_from_result_data(result_data: ResultData, get_final_results_only: bool = True) -> List[Record]:
+ """
+ Build a list of records from the given ResultData.
+
+ Args:
+ result_data (ResultData): The ResultData object containing the result data.
+ get_final_results_only (bool, optional): Whether to include only final results. Defaults to True.
+
+ Returns:
+ List[Record]: A list of records built from the ResultData.
+
+ """
+ messages = result_data.messages
+ if not messages:
+ return []
+ records = []
+ for message in messages:
+ message_dict = message if isinstance(message, dict) else message.model_dump()
+ if get_final_results_only:
+ result_data_dict = result_data.model_dump()
+ results = result_data_dict.get("results", {})
+ inner_result = results.get("result", {})
+ record = Record(data={"result": inner_result, "message": message_dict}, text_key="result")
+ records.append(record)
+ return records
+
+
+def format_flow_output_records(records: List[Record]) -> str:
+ """
+ Format the flow output records into a string.
+
+ Args:
+ records (List[Record]): The list of records to format.
+
+ Returns:
+ str: The formatted flow output records.
+
+ """
+ result = "Flow run output:\n"
+ results = "\n".join([record.result for record in records if record.data["message"]])
+ return result + results
diff --git a/src/backend/base/langflow/base/tools/flow_tool.py b/src/backend/base/langflow/base/tools/flow_tool.py
new file mode 100644
index 000000000..d0993bd99
--- /dev/null
+++ b/src/backend/base/langflow/base/tools/flow_tool.py
@@ -0,0 +1,117 @@
+from typing import Any, List, Optional, Type
+
+from asyncer import syncify
+from langchain.tools import BaseTool
+from langchain_core.runnables import RunnableConfig
+from langchain_core.tools import ToolException
+from pydantic.v1 import BaseModel
+
+from langflow.base.flow_processing.utils import build_records_from_result_data, format_flow_output_records
+from langflow.graph.graph.base import Graph
+from langflow.graph.vertex.base import Vertex
+from langflow.helpers.flow import build_schema_from_inputs, get_arg_names, get_flow_inputs, run_flow
+
+
+class FlowTool(BaseTool):
+ name: str
+ description: str
+ graph: Optional[Graph] = None
+ flow_id: Optional[str] = None
+ user_id: Optional[str] = None
+ inputs: List["Vertex"] = []
+ get_final_results_only: bool = True
+
+ @property
+ def args(self) -> dict:
+ schema = self.get_input_schema()
+ return schema.schema()["properties"]
+
+ def get_input_schema(self, config: Optional[RunnableConfig] = None) -> Type[BaseModel]:
+ """The tool's input schema."""
+ if self.args_schema is not None:
+ return self.args_schema
+ elif self.graph is not None:
+ return build_schema_from_inputs(self.name, get_flow_inputs(self.graph))
+ else:
+ raise ToolException("No input schema available.")
+
+ def _run(
+ self,
+ *args: Any,
+ **kwargs: Any,
+ ) -> str:
+ """Use the tool."""
+ args_names = get_arg_names(self.inputs)
+ if len(args_names) == len(args):
+ kwargs = {arg["arg_name"]: arg_value for arg, arg_value in zip(args_names, args)}
+ elif len(args_names) != len(args) and len(args) != 0:
+ raise ToolException(
+ "Number of arguments does not match the number of inputs. Pass keyword arguments instead."
+ )
+ tweaks = {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names}
+
+ run_outputs = syncify(run_flow, raise_sync_error=False)(
+ tweaks={key: {"input_value": value} for key, value in tweaks.items()},
+ flow_id=self.flow_id,
+ user_id=self.user_id,
+ )
+ if not run_outputs:
+ return "No output"
+ run_output = run_outputs[0]
+
+ records = []
+ if run_output is not None:
+ for output in run_output.outputs:
+ if output:
+ records.extend(
+ build_records_from_result_data(output, get_final_results_only=self.get_final_results_only)
+ )
+ return format_flow_output_records(records)
+
+ def validate_inputs(self, args_names: List[dict[str, str]], args: Any, kwargs: Any):
+ """Validate the inputs."""
+
+ if len(args) > 0 and len(args) != len(args_names):
+ raise ToolException(
+ "Number of positional arguments does not match the number of inputs. Pass keyword arguments instead."
+ )
+
+ if len(args) == len(args_names):
+ kwargs = {arg_name["arg_name"]: arg_value for arg_name, arg_value in zip(args_names, args)}
+
+ missing_args = [arg["arg_name"] for arg in args_names if arg["arg_name"] not in kwargs]
+ if missing_args:
+ raise ToolException(f"Missing required arguments: {', '.join(missing_args)}")
+
+ return kwargs
+
+ def build_tweaks_dict(self, args, kwargs):
+ args_names = get_arg_names(self.inputs)
+ kwargs = self.validate_inputs(args_names=args_names, args=args, kwargs=kwargs)
+ tweaks = {arg["component_name"]: kwargs[arg["arg_name"]] for arg in args_names}
+ return tweaks
+
+ async def _arun(
+ self,
+ *args: Any,
+ **kwargs: Any,
+ ) -> str:
+ """Use the tool asynchronously."""
+ tweaks = self.build_tweaks_dict(args, kwargs)
+ run_outputs = await run_flow(
+ tweaks={key: {"input_value": value} for key, value in tweaks.items()},
+ flow_id=self.flow_id,
+ user_id=self.user_id,
+ )
+ if not run_outputs:
+ return "No output"
+ run_output = run_outputs[0]
+
+ records = []
+ if run_output is not None:
+ for output in run_output.outputs:
+ if output:
+ records.extend(
+ build_records_from_result_data(output, get_final_results_only=self.get_final_results_only)
+ )
+ return format_flow_output_records(records)
diff --git a/src/backend/base/langflow/components/experimental/FlowTool.py b/src/backend/base/langflow/components/experimental/FlowTool.py
index 07f3b0e38..fa81f6351 100644
--- a/src/backend/base/langflow/components/experimental/FlowTool.py
+++ b/src/backend/base/langflow/components/experimental/FlowTool.py
@@ -1,14 +1,14 @@
from typing import Any, List, Optional
-from asyncer import syncify
-from langchain_core.tools import StructuredTool
+from loguru import logger
+
+from langflow.base.tools.flow_tool import FlowTool
from langflow.custom import CustomComponent
from langflow.field_typing import Tool
from langflow.graph.graph.base import Graph
-from langflow.helpers.flow import build_function_and_schema
+from langflow.helpers.flow import get_flow_inputs
from langflow.schema.dotdict import dotdict
from langflow.schema.schema import Record
-from loguru import logger
class FlowToolComponent(CustomComponent):
@@ -68,18 +68,20 @@ class FlowToolComponent(CustomComponent):
}
async def build(self, flow_name: str, name: str, description: str, return_direct: bool = False) -> Tool:
+ FlowTool.update_forward_refs()
flow_record = self.get_flow(flow_name)
if not flow_record:
raise ValueError("Flow not found.")
graph = Graph.from_payload(flow_record.data["data"])
- dynamic_flow_function, schema = build_function_and_schema(flow_record, graph)
- tool = StructuredTool.from_function(
- func=syncify(dynamic_flow_function, raise_sync_error=False), # type: ignore
- coroutine=dynamic_flow_function,
+ inputs = get_flow_inputs(graph)
+ tool = FlowTool(
name=name,
description=description,
+ graph=graph,
return_direct=return_direct,
- args_schema=schema,
+ inputs=inputs,
+ flow_id=str(flow_record.id),
+ user_id=str(self._user_id),
)
description_repr = repr(tool.description).strip("'")
args_str = "\n".join([f"- {arg_name}: {arg_data['description']}" for arg_name, arg_data in tool.args.items()])
diff --git a/src/backend/base/langflow/components/experimental/RunFlow.py b/src/backend/base/langflow/components/experimental/RunFlow.py
index d3769de7a..d2e7dd285 100644
--- a/src/backend/base/langflow/components/experimental/RunFlow.py
+++ b/src/backend/base/langflow/components/experimental/RunFlow.py
@@ -1,8 +1,9 @@
from typing import Any, List, Optional
+from langflow.base.flow_processing.utils import build_records_from_run_outputs
from langflow.custom import CustomComponent
from langflow.field_typing import NestedDict, Text
-from langflow.graph.schema import ResultData
+from langflow.graph.schema import RunOutputs
from langflow.schema import Record, dotdict
@@ -39,28 +40,17 @@ class RunFlowComponent(CustomComponent):
},
}
- def build_records_from_result_data(self, result_data: ResultData) -> List[Record]:
- messages = result_data.messages
- if not messages:
- return []
- records = []
- for message in messages:
- message_dict = message if isinstance(message, dict) else message.model_dump()
- record = Record(text=message_dict.get("text", ""), data={"result": result_data})
- records.append(record)
- return records
-
async def build(self, input_value: Text, flow_name: str, tweaks: NestedDict) -> List[Record]:
- results: List[Optional[ResultData]] = await self.run_flow(
+ results: List[Optional[RunOutputs]] = await self.run_flow(
inputs={"input_value": input_value}, flow_name=flow_name, tweaks=tweaks
)
if isinstance(results, list):
records = []
for result in results:
if result:
- records.extend(self.build_records_from_result_data(result))
+ records.extend(build_records_from_run_outputs(result))
else:
- records = self.build_records_from_result_data(results)
+ records = build_records_from_run_outputs()(results)
self.status = records
return records
diff --git a/src/backend/base/langflow/components/experimental/SubFlow.py b/src/backend/base/langflow/components/experimental/SubFlow.py
index 80e15c6ad..76a9538a4 100644
--- a/src/backend/base/langflow/components/experimental/SubFlow.py
+++ b/src/backend/base/langflow/components/experimental/SubFlow.py
@@ -2,9 +2,10 @@ from typing import Any, List, Optional
from loguru import logger
+from langflow.base.flow_processing.utils import build_records_from_result_data
from langflow.custom import CustomComponent
from langflow.graph.graph.base import Graph
-from langflow.graph.schema import ResultData, RunOutputs
+from langflow.graph.schema import RunOutputs
from langflow.graph.vertex.base import Vertex
from langflow.helpers.flow import get_flow_inputs
from langflow.schema import Record
@@ -92,21 +93,6 @@ class SubFlowComponent(CustomComponent):
},
}
- def build_records_from_result_data(self, result_data: ResultData, get_final_results_only: bool) -> List[Record]:
- messages = result_data.messages
- if not messages:
- return []
- records = []
- for message in messages:
- message_dict = message if isinstance(message, dict) else message.model_dump()
- if get_final_results_only:
- result_data_dict = result_data.model_dump()
- results = result_data_dict.get("results", {})
- inner_result = results.get("result", {})
- record = Record(data={"result": inner_result, "message": message_dict}, text_key="result")
- records.append(record)
- return records
-
async def build(self, flow_name: str, get_final_results_only: bool = True, **kwargs) -> List[Record]:
tweaks = {key: {"input_value": value} for key, value in kwargs.items()}
run_outputs: List[Optional[RunOutputs]] = await self.run_flow(
@@ -121,7 +107,7 @@ class SubFlowComponent(CustomComponent):
if run_output is not None:
for output in run_output.outputs:
if output:
- records.extend(self.build_records_from_result_data(output, get_final_results_only))
+ records.extend(build_records_from_result_data(output, get_final_results_only))
self.status = records
logger.debug(records)
diff --git a/src/backend/base/langflow/components/models/OllamaModel.py b/src/backend/base/langflow/components/models/OllamaModel.py
index d9ba48501..5806ad770 100644
--- a/src/backend/base/langflow/components/models/OllamaModel.py
+++ b/src/backend/base/langflow/components/models/OllamaModel.py
@@ -1,16 +1,21 @@
-from typing import Dict, List, Optional
-# from langchain_community.chat_models import ChatOllama
-from langchain_community.chat_models import ChatOllama
+from typing import Any, Dict, List, Optional, Union
+
+
+from langchain_community.chat_models.ollama import ChatOllama
from langflow.base.constants import STREAM_INFO_TEXT
from langflow.base.models.model import LCModelComponent
+from langchain_core.caches import BaseCache
-# from langchain.chat_models import ChatOllama
from langflow.field_typing import Text
-# whe When a callback component is added to Langflow, the comment must be uncommented.
-# from langchain.callbacks.manager import CallbackManager
+
+import asyncio
+import json
+
+import httpx
+
class ChatOllamaComponent(LCModelComponent):
@@ -20,11 +25,19 @@ class ChatOllamaComponent(LCModelComponent):
field_order = [
"base_url",
+ "headers",
+
+ "keep_alive_flag",
+ "keep_alive",
+
+ "metadata",
"model",
+
+
"temperature",
"cache",
- "callback_manager",
- "callbacks",
+
+
"format",
"metadata",
"mirostat",
@@ -54,12 +67,41 @@ class ChatOllamaComponent(LCModelComponent):
"base_url": {
"display_name": "Base URL",
"info": "Endpoint of the Ollama API. Defaults to 'http://localhost:11434' if not specified.",
+
+ },
+
+
+ "format": {
+ "display_name": "Format",
+ "info": "Specify the format of the output (e.g., json)",
"advanced": True,
},
+ "headers": {
+ "display_name": "Headers",
+ "advanced": True,
+
+
+ },
+
+ "keep_alive_flag": {
+ "display_name": "Unload interval",
+ "options": ["Keep", "Immediately","Minute", "Hour", "sec" ],
+ "real_time_refresh": True,
+ "refresh_button": True,
+ },
+ "keep_alive": {
+ "display_name": "interval",
+ "info": "How long the model will stay loaded into memory.",
+ },
+
+
+
"model": {
"display_name": "Model Name",
- "value": "llama2",
+ "options": [],
"info": "Refer to https://ollama.ai/library for more models.",
+ "real_time_refresh": True,
+ "refresh_button": True,
},
"temperature": {
"display_name": "Temperature",
@@ -67,25 +109,8 @@ class ChatOllamaComponent(LCModelComponent):
"value": 0.8,
"info": "Controls the creativity of model responses.",
},
- "cache": {
- "display_name": "Cache",
- "field_type": "bool",
- "info": "Enable or disable caching.",
- "advanced": True,
- "value": False,
- },
- ### When a callback component is added to Langflow, the comment must be uncommented. ###
- # "callback_manager": {
- # "display_name": "Callback Manager",
- # "info": "Optional callback manager for additional functionality.",
- # "advanced": True,
- # },
- # "callbacks": {
- # "display_name": "Callbacks",
- # "info": "Callbacks to execute during model runtime.",
- # "advanced": True,
- # },
- ########################################################################################
+
+
"format": {
"display_name": "Format",
"field_type": "str",
@@ -101,20 +126,24 @@ class ChatOllamaComponent(LCModelComponent):
"display_name": "Mirostat",
"options": ["Disabled", "Mirostat", "Mirostat 2.0"],
"info": "Enable/disable Mirostat sampling for controlling perplexity.",
- "value": "Disabled",
- "advanced": True,
+ "advanced": False,
+ "real_time_refresh": True,
+ "refresh_button": True,
+
},
"mirostat_eta": {
"display_name": "Mirostat Eta",
"field_type": "float",
"info": "Learning rate for Mirostat algorithm. (Default: 0.1)",
"advanced": True,
+ "real_time_refresh": True,
},
"mirostat_tau": {
"display_name": "Mirostat Tau",
"field_type": "float",
"info": "Controls the balance between coherence and diversity of the output. (Default: 5.0)",
"advanced": True,
+ "real_time_refresh": True,
},
"num_ctx": {
"display_name": "Context Window Size",
@@ -211,21 +240,74 @@ class ChatOllamaComponent(LCModelComponent):
},
}
+ def update_build_config(self, build_config: dict, field_value: Any, field_name: str | None = None):
+ if field_name == "mirostat":
+ if field_value == "Disabled":
+ build_config["mirostat_eta"]["advanced"] = True
+ build_config["mirostat_tau"]["advanced"] = True
+ build_config["mirostat_eta"]["value"] = None
+ build_config["mirostat_tau"]["value"] = None
+
+ else:
+ build_config["mirostat_eta"]["advanced"] = False
+ build_config["mirostat_tau"]["advanced"] = False
+
+ if field_value == "Mirostat 2.0":
+ build_config["mirostat_eta"]["value"] = 0.2
+ build_config["mirostat_tau"]["value"] = 10
+ else:
+ build_config["mirostat_eta"]["value"] = 0.1
+ build_config["mirostat_tau"]["value"] = 5
+
+ if field_name == "model":
+ base_url = build_config.get("base_url", {}).get(
+ "value", "http://localhost:11434")
+ build_config["model"]["options"] = self.get_model(
+ base_url + "/api/tags")
+
+ if field_name == "keep_alive_flag":
+ if field_value == "Keep":
+ build_config["keep_alive"]["value"] = "-1"
+ build_config["keep_alive"]["advanced"] = True
+ elif field_value == "Immediately":
+ build_config["keep_alive"]["value"] = "0"
+ build_config["keep_alive"]["advanced"] = True
+ else:
+ build_config["keep_alive"]["advanced"] = False
+
+ return build_config
+
+
+
+
+ def get_model(self, url: str) -> List[str]:
+ try:
+ with httpx.Client() as client:
+ response = client.get(url)
+ response.raise_for_status()
+ data = response.json()
+
+ model_names = [model['name']
+ for model in data.get("models", [])]
+ return model_names
+ except Exception as e:
+ raise ValueError("Could not retrieve models") from e
+ return [""]
+
def build(
self,
base_url: Optional[str],
model: str,
input_value: Text,
- mirostat: Optional[str],
+
+ mirostat: Optional[str],
mirostat_eta: Optional[float] = None,
mirostat_tau: Optional[float] = None,
- ### When a callback component is added to Langflow, the comment must be uncommented.###
- # callback_manager: Optional[CallbackManager] = None,
- # callbacks: Optional[List[Callbacks]] = None,
- #######################################################################################
+
repeat_last_n: Optional[int] = None,
verbose: Optional[bool] = None,
- cache: Optional[bool] = None,
+ keep_alive: Optional[int] = None,
+ keep_alive_flag: Optional[str] = None,
num_ctx: Optional[int] = None,
num_gpu: Optional[int] = None,
format: Optional[str] = None,
@@ -244,33 +326,39 @@ class ChatOllamaComponent(LCModelComponent):
stream: bool = False,
system_message: Optional[str] = None,
) -> Text:
+
if not base_url:
base_url = "http://localhost:11434"
- # Mapping mirostat settings to their corresponding values
- mirostat_options = {"Mirostat": 1, "Mirostat 2.0": 2}
- # Default to 0 for 'Disabled'
- mirostat_value = mirostat_options.get(mirostat, 0) # type: ignore
- # Set mirostat_eta and mirostat_tau to None if mirostat is disabled
- if mirostat_value == 0:
- mirostat_eta = None
- mirostat_tau = None
+ if keep_alive_flag == "Minute":
+ keep_alive_instance = f"{keep_alive}m"
+ elif keep_alive_flag == "Hour":
+ keep_alive_instance = f"{keep_alive}h"
+ elif keep_alive_flag == "sec":
+ keep_alive_instance = f"{keep_alive}s"
+ elif keep_alive_flag == "Keep":
+ keep_alive_instance = "-1"
+ elif keep_alive_flag == "Immediately":
+ keep_alive_instance = "0"
+ else:
+ keep_alive_instance = "Invalid option"
+
+ mirostat_instance = 0
+
+ if mirostat == "disable":
+ mirostat_instance = 0
# Mapping system settings to their corresponding values
llm_params = {
"base_url": base_url,
- "cache": cache,
"model": model,
- "mirostat": mirostat_value,
+ "mirostat": mirostat_instance,
+ "keep_alive": keep_alive_instance,
"format": format,
"metadata": metadata,
"tags": tags,
- ## When a callback component is added to Langflow, the comment must be uncommented.##
- # "callback_manager": callback_manager,
- # "callbacks": callbacks,
- #####################################################################################
"mirostat_eta": mirostat_eta,
"mirostat_tau": mirostat_tau,
"num_ctx": num_ctx,
diff --git a/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py b/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py
index 0046063d1..228e100e4 100644
--- a/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py
+++ b/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py
@@ -1,5 +1,6 @@
from typing import List, Optional
+import chromadb
from chromadb.config import Settings
from langchain_chroma import Chroma
@@ -91,7 +92,7 @@ class ChromaSearchComponent(LCVectorStoreComponent):
# Chroma settings
chroma_settings = None
-
+ client = None
if chroma_server_host is not None:
chroma_settings = Settings(
chroma_server_cors_allow_origins=chroma_server_cors_allow_origins or [],
@@ -100,13 +101,14 @@ class ChromaSearchComponent(LCVectorStoreComponent):
chroma_server_grpc_port=chroma_server_grpc_port or None,
chroma_server_ssl_enabled=chroma_server_ssl_enabled,
)
+ client = chromadb.HttpClient(settings=chroma_settings)
if index_directory:
index_directory = self.resolve_path(index_directory)
vector_store = Chroma(
embedding_function=embedding,
collection_name=collection_name,
persist_directory=index_directory,
- client_settings=chroma_settings,
+ client=client,
)
return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)
diff --git a/src/backend/base/langflow/components/vectorstores/Chroma.py b/src/backend/base/langflow/components/vectorstores/Chroma.py
index 9683d7a98..3671dbbdb 100644
--- a/src/backend/base/langflow/components/vectorstores/Chroma.py
+++ b/src/backend/base/langflow/components/vectorstores/Chroma.py
@@ -1,5 +1,6 @@
from typing import List, Optional, Union
+import chromadb
from chromadb.config import Settings
from langchain_chroma import Chroma
from langchain_core.embeddings import Embeddings
@@ -81,7 +82,7 @@ class ChromaComponent(CustomComponent):
# Chroma settings
chroma_settings = None
-
+ client = None
if chroma_server_host is not None:
chroma_settings = Settings(
chroma_server_cors_allow_origins=chroma_server_cors_allow_origins or [],
@@ -90,6 +91,7 @@ class ChromaComponent(CustomComponent):
chroma_server_grpc_port=chroma_server_grpc_port or None,
chroma_server_ssl_enabled=chroma_server_ssl_enabled,
)
+ client = chromadb.HttpClient(settings=chroma_settings)
# If documents, then we need to create a Chroma instance using .from_documents
@@ -111,12 +113,12 @@ class ChromaComponent(CustomComponent):
persist_directory=index_directory,
collection_name=collection_name,
embedding=embedding,
- client_settings=chroma_settings,
+ client=client,
)
else:
chroma = Chroma(
persist_directory=index_directory,
- client_settings=chroma_settings,
+ client=client,
embedding_function=embedding,
)
return chroma
diff --git a/src/backend/base/langflow/helpers/flow.py b/src/backend/base/langflow/helpers/flow.py
index 36b852a99..a20462f3d 100644
--- a/src/backend/base/langflow/helpers/flow.py
+++ b/src/backend/base/langflow/helpers/flow.py
@@ -1,10 +1,13 @@
from typing import TYPE_CHECKING, Any, Awaitable, Callable, List, Optional, Tuple, Type, Union, cast
+from uuid import UUID
+from pydantic.v1 import BaseModel, Field, create_model
+from sqlmodel import select
+
+from langflow.graph.schema import RunOutputs
from langflow.schema.schema import INPUT_FIELD_NAME, Record
from langflow.services.database.models.flow.model import Flow
from langflow.services.deps import session_scope
-from pydantic.v1 import BaseModel, Field, create_model
-from sqlmodel import select
if TYPE_CHECKING:
from langflow.graph.graph.base import Graph
@@ -51,7 +54,7 @@ async def load_flow(
raise ValueError(f"Flow {flow_id} not found")
if tweaks:
graph_data = process_tweaks(graph_data=graph_data, tweaks=tweaks)
- graph = Graph.from_payload(graph_data, flow_id=flow_id)
+ graph = Graph.from_payload(graph_data, flow_id=flow_id, user_id=user_id)
return graph
@@ -67,25 +70,29 @@ async def run_flow(
flow_id: Optional[str] = None,
flow_name: Optional[str] = None,
user_id: Optional[str] = None,
-) -> Any:
+) -> List[RunOutputs]:
if user_id is None:
raise ValueError("Session is invalid")
graph = await load_flow(user_id, flow_id, flow_name, tweaks)
if inputs is None:
inputs = []
+ if isinstance(inputs, dict):
+ inputs = [inputs]
inputs_list = []
inputs_components = []
types = []
for input_dict in inputs:
inputs_list.append({INPUT_FIELD_NAME: cast(str, input_dict.get("input_value"))})
inputs_components.append(input_dict.get("components", []))
- types.append(input_dict.get("type", []))
+ types.append(input_dict.get("type", "chat"))
return await graph.arun(inputs_list, inputs_components=inputs_components, types=types)
-def generate_function_for_flow(inputs: List["Vertex"], flow_id: str) -> Callable[..., Awaitable[Any]]:
+def generate_function_for_flow(
+ inputs: List["Vertex"], flow_id: str, user_id: str | UUID | None
+) -> Callable[..., Awaitable[Any]]:
"""
Generate a dynamic flow function based on the given inputs and flow ID.
@@ -129,11 +136,23 @@ async def flow_function({func_args}):
tweaks = {{ {arg_mappings} }}
from langflow.helpers.flow import run_flow
from langchain_core.tools import ToolException
+ from langflow.base.flow_processing.utils import build_records_from_result_data, format_flow_output_records
try:
- return await run_flow(
+ run_outputs = await run_flow(
tweaks={{key: {{'input_value': value}} for key, value in tweaks.items()}},
flow_id="{flow_id}",
+ user_id="{user_id}"
)
+ if not run_outputs:
+ return []
+ run_output = run_outputs[0]
+
+ records = []
+ if run_output is not None:
+ for output in run_output.outputs:
+ if output:
+ records.extend(build_records_from_result_data(output, get_final_results_only=True))
+ return format_flow_output_records(records)
except Exception as e:
raise ToolException(f'Error running flow: ' + e)
"""
@@ -145,7 +164,7 @@ async def flow_function({func_args}):
def build_function_and_schema(
- flow_record: Record, graph: "Graph"
+ flow_record: Record, graph: "Graph", user_id: str | UUID | None
) -> Tuple[Callable[..., Awaitable[Any]], Type[BaseModel]]:
"""
Builds a dynamic function and schema for a given flow.
@@ -159,7 +178,7 @@ def build_function_and_schema(
"""
flow_id = flow_record.id
inputs = get_flow_inputs(graph)
- dynamic_flow_function = generate_function_for_flow(inputs, flow_id)
+ dynamic_flow_function = generate_function_for_flow(inputs, flow_id, user_id=user_id)
schema = build_schema_from_inputs(flow_record.name, inputs)
return dynamic_flow_function, schema
@@ -200,3 +219,19 @@ def build_schema_from_inputs(name: str, inputs: List["Vertex"]) -> Type[BaseMode
description = input_.description
fields[field_name] = (str, Field(default="", description=description))
return create_model(name, **fields) # type: ignore
+
+
+def get_arg_names(inputs: List["Vertex"]) -> List[dict[str, str]]:
+ """
+ Returns a list of dictionaries containing the component name and its corresponding argument name.
+
+ Args:
+ inputs (List[Vertex]): A list of Vertex objects representing the inputs.
+
+ Returns:
+ List[dict[str, str]]: A list of dictionaries, where each dictionary contains the component name and its argument name.
+ """
+ return [
+ {"component_name": input_.display_name, "arg_name": input_.display_name.lower().replace(" ", "_")}
+ for input_ in inputs
+ ]
diff --git a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json
index a4363ba2b..4cb469ece 100644
--- a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json
+++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json
@@ -572,7 +572,7 @@
"advanced": false,
"dynamic": false,
"info": "",
- "load_from_db": false,
+ "load_from_db": true,
"title_case": false,
"input_types": [
"Text"
@@ -965,7 +965,7 @@
"advanced": false,
"dynamic": false,
"info": "The OpenAI API Key to use for the OpenAI model.",
- "load_from_db": false,
+ "load_from_db": true,
"title_case": false,
"input_types": [
"Text"
@@ -2846,7 +2846,7 @@
"advanced": false,
"dynamic": false,
"info": "",
- "load_from_db": false,
+ "load_from_db": true,
"title_case": false,
"input_types": [
"Text"
diff --git a/src/backend/base/langflow/services/settings/base.py b/src/backend/base/langflow/services/settings/base.py
index 05a368c9b..f62ccacd4 100644
--- a/src/backend/base/langflow/services/settings/base.py
+++ b/src/backend/base/langflow/services/settings/base.py
@@ -104,6 +104,10 @@ class Settings(BaseSettings):
"""Whether to store environment variables as Global Variables in the database."""
variables_to_get_from_environment: list[str] = VARIABLES_TO_GET_FROM_ENVIRONMENT
"""List of environment variables to get from the environment and store in the database."""
+ worker_timeout: int = 300
+ """Timeout for the API calls in seconds."""
+ frontend_timeout: int = 0
+ """Timeout for the frontend API calls in seconds."""
@field_validator("config_dir", mode="before")
def set_langflow_dir(cls, value):
diff --git a/src/backend/base/langflow/services/settings/service.py b/src/backend/base/langflow/services/settings/service.py
index 0d9d63bc4..f7ef2980d 100644
--- a/src/backend/base/langflow/services/settings/service.py
+++ b/src/backend/base/langflow/services/settings/service.py
@@ -42,3 +42,7 @@ class SettingsService(Service):
CONFIG_DIR=settings.config_dir,
)
return cls(settings, auth_settings)
+
+ def set(self, key, value):
+ setattr(self.settings, key, value)
+ return self.settings
diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml
index ce7557464..1ea2b0037 100644
--- a/src/backend/base/pyproject.toml
+++ b/src/backend/base/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "langflow-base"
-version = "0.0.49"
+version = "0.0.50"
description = "A Python package with a built-in web application"
authors = ["Langflow "]
maintainers = [
diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx
index 922ec9994..510500e2b 100644
--- a/src/frontend/src/App.tsx
+++ b/src/frontend/src/App.tsx
@@ -1,3 +1,4 @@
+import axios from "axios";
import { useContext, useEffect, useState } from "react";
import { ErrorBoundary } from "react-error-boundary";
import { useNavigate } from "react-router-dom";
@@ -15,6 +16,7 @@ import {
} from "./constants/constants";
import { AuthContext } from "./contexts/authContext";
import { autoLogin, getGlobalVariables, getHealth } from "./controllers/API";
+import { setupAxiosDefaults } from "./controllers/API/utils";
import useTrackLastVisitedPath from "./hooks/use-track-last-visited-path";
import Router from "./routes";
import useAlertStore from "./stores/alertStore";
@@ -28,10 +30,10 @@ export default function App() {
useTrackLastVisitedPath();
const removeFromTempNotificationList = useAlertStore(
- (state) => state.removeFromTempNotificationList,
+ (state) => state.removeFromTempNotificationList
);
const tempNotificationList = useAlertStore(
- (state) => state.tempNotificationList,
+ (state) => state.tempNotificationList
);
const [fetchError, setFetchError] = useState(false);
const isLoading = useFlowsManagerStore((state) => state.isLoading);
@@ -49,7 +51,7 @@ export default function App() {
const refreshVersion = useDarkStore((state) => state.refreshVersion);
const refreshStars = useDarkStore((state) => state.refreshStars);
const setGlobalVariables = useGlobalVariablesStore(
- (state) => state.setGlobalVariables,
+ (state) => state.setGlobalVariables
);
const checkHasStore = useStoreStore((state) => state.checkHasStore);
const navigate = useNavigate();
@@ -114,9 +116,11 @@ export default function App() {
return new Promise(async (resolve, reject) => {
if (isAuthenticated) {
try {
+ await setupAxiosDefaults();
await getFoldersApi();
await getTypes();
await refreshFlows();
+ console.log(axios.defaults);
const res = await getGlobalVariables();
setGlobalVariables(res);
checkHasStore();
diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx
index 363576ae0..d630c474f 100644
--- a/src/frontend/src/controllers/API/api.tsx
+++ b/src/frontend/src/controllers/API/api.tsx
@@ -48,7 +48,7 @@ function ApiInterceptor() {
}
await clearBuildVerticesState(error);
return Promise.reject(error);
- },
+ }
);
const isAuthorizedURL = (url) => {
@@ -65,10 +65,10 @@ function ApiInterceptor() {
const parsedURL = new URL(url);
const isDomainAllowed = authorizedDomains.some(
- (domain) => parsedURL.origin === new URL(domain).origin,
+ (domain) => parsedURL.origin === new URL(domain).origin
);
const isEndpointAllowed = authorizedEndpoints.some((endpoint) =>
- parsedURL.pathname.includes(endpoint),
+ parsedURL.pathname.includes(endpoint)
);
return isDomainAllowed || isEndpointAllowed;
@@ -112,7 +112,7 @@ function ApiInterceptor() {
},
(error) => {
return Promise.reject(error);
- },
+ }
);
return () => {
@@ -144,7 +144,7 @@ function ApiInterceptor() {
if (error?.config?.headers) {
delete error.config.headers["Authorization"];
error.config.headers["Authorization"] = `Bearer ${cookies.get(
- "access_token_lf",
+ "access_token_lf"
)}`;
const response = await axios.request(error.config);
return response;
diff --git a/src/frontend/src/controllers/API/utils.tsx b/src/frontend/src/controllers/API/utils.tsx
new file mode 100644
index 000000000..3991caa2e
--- /dev/null
+++ b/src/frontend/src/controllers/API/utils.tsx
@@ -0,0 +1,32 @@
+import axios from "axios";
+import { BASE_URL_API } from "../../constants/constants";
+
+/**
+ * Fetches the configuration data from the API.
+ * @returns {Promise} A promise that resolves to the configuration data.
+ * @throws {Error} If there was an error fetching the configuration data.
+ */
+export async function fetchConfig() {
+ try {
+ const response = await axios.get(`${BASE_URL_API}config`);
+ return response.data;
+ } catch (error) {
+ console.error("Failed to fetch configuration:", error);
+ throw error;
+ }
+}
+
+/**
+ * Sets up default configurations for Axios.
+ * Fetches the timeout configuration and sets it as the default timeout for Axios requests.
+ */
+export async function setupAxiosDefaults() {
+ const config = await fetchConfig();
+ // Create Axios instance with the fetched timeout configuration
+
+ const timeoutInMilliseconds = config.frontend_timeout
+ ? config.frontend_timeout * 1000
+ : 30000;
+ axios.defaults.baseURL = "";
+ axios.defaults.timeout = timeoutInMilliseconds;
+}
diff --git a/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx b/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx
index b77ff3c5e..a15c3ea94 100644
--- a/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx
+++ b/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx
@@ -8,51 +8,51 @@
export default function getPythonApiCode(
flowId: string,
isAuth: boolean,
- tweaksBuildedObject,
+ tweaksBuildedObject
): string {
const tweaksObject = tweaksBuildedObject[0];
return `import requests
- from typing import Optional
+from typing import Optional
- BASE_API_URL = "${window.location.protocol}//${window.location.host}/api/v1/run"
- FLOW_ID = "${flowId}"
- # You can tweak the flow by adding a tweaks dictionary
- # e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
- TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
+BASE_API_URL = "${window.location.protocol}//${window.location.host}/api/v1/run"
+FLOW_ID = "${flowId}"
+# You can tweak the flow by adding a tweaks dictionary
+# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
+TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
- def run_flow(message: str,
- flow_id: str,
- output_type: str = "chat",
- input_type: str = "chat",
- tweaks: Optional[dict] = None,
- api_key: Optional[str] = None) -> dict:
- """
- Run a flow with a given message and optional tweaks.
+def run_flow(message: str,
+ flow_id: str,
+ output_type: str = "chat",
+ input_type: str = "chat",
+ tweaks: Optional[dict] = None,
+ api_key: Optional[str] = None) -> dict:
+ """
+ Run a flow with a given message and optional tweaks.
- :param message: The message to send to the flow
- :param flow_id: The ID of the flow to run
- :param tweaks: Optional tweaks to customize the flow
- :return: The JSON response from the flow
- """
- api_url = f"{BASE_API_URL}/{flow_id}"
+ :param message: The message to send to the flow
+ :param flow_id: The ID of the flow to run
+ :param tweaks: Optional tweaks to customize the flow
+ :return: The JSON response from the flow
+ """
+ api_url = f"{BASE_API_URL}/{flow_id}"
- payload = {
- "input_value": message,
- "output_type": output_type,
- "input_type": input_type,
- }
- headers = None
- if tweaks:
- payload["tweaks"] = tweaks
- if api_key:
- headers = {"x-api-key": api_key}
- response = requests.post(api_url, json=payload, headers=headers)
- return response.json()
+ payload = {
+ "input_value": message,
+ "output_type": output_type,
+ "input_type": input_type,
+ }
+ headers = None
+ if tweaks:
+ payload["tweaks"] = tweaks
+ if api_key:
+ headers = {"x-api-key": api_key}
+ response = requests.post(api_url, json=payload, headers=headers)
+ return response.json()
- # Setup any tweaks you want to apply to the flow
- message = "message"
- ${!isAuth ? `api_key = ""` : ""}
- print(run_flow(message=message, flow_id=FLOW_ID, tweaks=TWEAKS${
+# Setup any tweaks you want to apply to the flow
+message = "message"
+${!isAuth ? `api_key = ""` : ""}
+print(run_flow(message=message, flow_id=FLOW_ID, tweaks=TWEAKS${
!isAuth ? `, api_key=api_key` : ""
}))`;
}
diff --git a/src/frontend/src/modals/apiModal/utils/get-python-code.tsx b/src/frontend/src/modals/apiModal/utils/get-python-code.tsx
index 9e1ad8052..9fd8048f2 100644
--- a/src/frontend/src/modals/apiModal/utils/get-python-code.tsx
+++ b/src/frontend/src/modals/apiModal/utils/get-python-code.tsx
@@ -6,15 +6,15 @@
*/
export default function getPythonCode(
flowName: string,
- tweaksBuildedObject,
+ tweaksBuildedObject
): string {
const tweaksObject = tweaksBuildedObject[0];
return `from langflow.load import run_flow_from_json
- TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
+TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
- result = run_flow_from_json(flow="${flowName}.json",
- input_value="message",
- fallback_to_env_vars=True, # False by default
- tweaks=TWEAKS)`;
+result = run_flow_from_json(flow="${flowName}.json",
+ input_value="message",
+ fallback_to_env_vars=True, # False by default
+ tweaks=TWEAKS)`;
}
diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
index 1203aab65..cbf941fbb 100644
--- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
@@ -271,7 +271,7 @@ export default function NodeToolbarComponent({
selected &&
(hasApiKey || hasStore) &&
(event.ctrlKey || event.metaKey) &&
- event.key === "u"
+ event.key.toUpperCase() === "U"
) {
event.preventDefault();
handleSelectChange("update");
@@ -280,7 +280,7 @@ export default function NodeToolbarComponent({
selected &&
isGroup &&
(event.ctrlKey || event.metaKey) &&
- event.key === "g"
+ event.key.toUpperCase() === "G"
) {
event.preventDefault();
handleSelectChange("ungroup");
@@ -290,7 +290,7 @@ export default function NodeToolbarComponent({
(hasApiKey || hasStore) &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
- event.key === "S"
+ event.key.toUpperCase() === "S"
) {
event.preventDefault();
setShowconfirmShare((state) => !state);
@@ -300,7 +300,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
- event.key === "Q"
+ event.key.toUpperCase() === "Q"
) {
event.preventDefault();
if (isMinimal) {
@@ -317,7 +317,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
- event.key === "U"
+ event.key.toUpperCase() === "U"
) {
event.preventDefault();
if (hasCode) return setOpenModal((state) => !state);
@@ -327,12 +327,16 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
- event.key === "A"
+ event.key.toUpperCase() === "A"
) {
event.preventDefault();
setShowModalAdvanced((state) => !state);
}
- if (selected && (event.ctrlKey || event.metaKey) && event.key === "s") {
+ if (
+ selected &&
+ (event.ctrlKey || event.metaKey) &&
+ event.key.toUpperCase() === "S"
+ ) {
if (isSaved) {
event.preventDefault();
return setShowOverrideModal((state) => !state);
@@ -347,7 +351,7 @@ export default function NodeToolbarComponent({
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
- event.key === "D"
+ event.key.toUpperCase() === "D"
) {
event.preventDefault();
if (data.node?.documentation) {
@@ -357,7 +361,11 @@ export default function NodeToolbarComponent({
title: `${data.id} docs is not available at the moment.`,
});
}
- if (selected && (event.ctrlKey || event.metaKey) && event.key === "j") {
+ if (
+ selected &&
+ (event.ctrlKey || event.metaKey) &&
+ event.key.toUpperCase() === "J"
+ ) {
event.preventDefault();
downloadNode(flowComponent!);
}