diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml
index b5424b367..f63920703 100644
--- a/.github/workflows/docker-build.yml
+++ b/.github/workflows/docker-build.yml
@@ -30,6 +30,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
+ id: qemu
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
@@ -52,6 +53,7 @@ jobs:
with:
context: .
push: true
+ platforms: "linux/amd64,linux/arm64/v8"
file: ${{ env.DOCKERFILE }}
tags: ${{ env.TAGS }}
- name: Wait for Docker Hub to propagate
@@ -62,6 +64,7 @@ jobs:
with:
context: .
push: true
+ platforms: "linux/amd64,linux/arm64/v8"
file: ./docker/build_and_push_backend.Dockerfile
build-args: |
LANGFLOW_IMAGE=langflowai/langflow:${{ inputs.version }}
@@ -75,6 +78,7 @@ jobs:
context: .
push: true
file: ./docker/frontend/build_and_push_frontend.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow-frontend:${{ inputs.version }}
langflowai/langflow-frontend:1.0-alpha
diff --git a/.github/workflows/docker_test.yml b/.github/workflows/docker_test.yml
index f46010358..9be7beb00 100644
--- a/.github/workflows/docker_test.yml
+++ b/.github/workflows/docker_test.yml
@@ -8,6 +8,7 @@ on:
- "poetry.lock"
- "pyproject.toml"
- "src/backend/**"
+ - ".github/workflows/docker_test.yml"
pull_request:
branches: [dev]
paths:
@@ -15,12 +16,13 @@ on:
- "poetry.lock"
- "pyproject.toml"
- "src/**"
+ - ".github/workflows/docker_test.yml"
env:
POETRY_VERSION: "1.8.2"
jobs:
- build:
+ test-docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
@@ -59,3 +61,20 @@ jobs:
docker build -t langflowai/langflow-frontend:latest-dev \
-f docker/frontend/build_and_push_frontend.Dockerfile \
.
+ test-multi-arch-build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v4
+ - name: Set up QEMU
+ uses: docker/setup-qemu-action@v3
+ id: qemu
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v3
+ - name: Build and push
+ uses: docker/build-push-action@v5
+ with:
+ context: .
+ push: false
+ file: ./docker/build_and_push.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
+ tags: langflowai/langflow:latest-dev
diff --git a/.github/workflows/pre-release-base.yml b/.github/workflows/pre-release-base.yml
index 6045038be..6f1e4fe8e 100644
--- a/.github/workflows/pre-release-base.yml
+++ b/.github/workflows/pre-release-base.yml
@@ -60,6 +60,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
+ id: qemu
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
@@ -73,5 +74,6 @@ jobs:
context: .
push: true
file: ./docker/build_and_push_base.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow:base-${{ needs.release.outputs.version }}
diff --git a/.github/workflows/pre-release-langflow.yml b/.github/workflows/pre-release-langflow.yml
index f3909f7b1..79c1d6af5 100644
--- a/.github/workflows/pre-release-langflow.yml
+++ b/.github/workflows/pre-release-langflow.yml
@@ -66,6 +66,7 @@ jobs:
- uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
+ id: qemu
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
@@ -79,6 +80,7 @@ jobs:
context: .
push: true
file: ./docker/build_and_push.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow:${{ needs.release.outputs.version }}
langflowai/langflow:1.0-alpha
@@ -88,6 +90,7 @@ jobs:
context: .
push: true
file: ./docker/frontend/build_and_push_frontend.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow-frontend:${{ needs.release.outputs.version }}
langflowai/langflow-frontend:1.0-alpha
@@ -99,6 +102,7 @@ jobs:
context: .
push: true
file: ./docker/build_and_push_backend.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
build-args: |
LANGFLOW_IMAGE=langflowai/langflow:${{ needs.release.outputs.version }}
tags: |
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 851f06424..364289b90 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -38,6 +38,7 @@ jobs:
poetry publish
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
+ id: qemu
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
@@ -51,6 +52,7 @@ jobs:
context: .
push: true
file: ./docker/build_and_push.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow:${{ steps.check-version.outputs.version }}
langflowai/langflow:latest
@@ -62,6 +64,7 @@ jobs:
context: .
push: true
file: ./docker/build_and_push_backend.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
build-args: |
LANGFLOW_IMAGE=langflowai/langflow:${{ steps.check-version.outputs.version }}
tags: |
@@ -73,6 +76,7 @@ jobs:
context: .
push: true
file: ./docker/frontend/build_and_push_frontend.Dockerfile
+ platforms: "linux/amd64,linux/arm64/v8"
tags: |
langflowai/langflow-frontend:${{ steps.check-version.outputs.version }}
langflowai/langflow-frontend:latest
diff --git a/docker/build_and_push.Dockerfile b/docker/build_and_push.Dockerfile
index 63521d06a..43d9a0272 100644
--- a/docker/build_and_push.Dockerfile
+++ b/docker/build_and_push.Dockerfile
@@ -6,7 +6,9 @@
# BUILDER-BASE
# Used to build deps + create our virtual environment
################################
-FROM python:3.12-slim as builder-base
+
+# force platform to the current architecture to increase build speed time on multi-platform builds
+FROM --platform=$BUILDPLATFORM python:3.12-slim as builder-base
ENV PYTHONDONTWRITEBYTECODE=1 \
\
@@ -59,6 +61,12 @@ RUN $POETRY_HOME/bin/poetry lock --no-update \
################################
FROM python:3.12-slim as runtime
+RUN apt-get -y update \
+ && apt-get install --no-install-recommends -y \
+ curl \
+ && apt-get clean \
+ && rm -rf /var/lib/apt/lists/*
+
LABEL org.opencontainers.image.title=langflow
LABEL org.opencontainers.image.authors=['Langflow']
LABEL org.opencontainers.image.licenses=MIT
diff --git a/docker/frontend/build_and_push_frontend.Dockerfile b/docker/frontend/build_and_push_frontend.Dockerfile
index e954a801e..46c5ffdeb 100644
--- a/docker/frontend/build_and_push_frontend.Dockerfile
+++ b/docker/frontend/build_and_push_frontend.Dockerfile
@@ -4,7 +4,9 @@
################################
# BUILDER-BASE
################################
-FROM node:lts-bookworm-slim as builder-base
+
+# force platform to the current architecture to increase build speed time on multi-platform builds
+FROM --platform=$BUILDPLATFORM node:lts-bookworm-slim as builder-base
COPY src/frontend /frontend
RUN cd /frontend && npm install && npm run build
diff --git a/docs/docs/administration/api.mdx b/docs/docs/administration/api.mdx
index 115cdc666..de8533cd2 100644
--- a/docs/docs/administration/api.mdx
+++ b/docs/docs/administration/api.mdx
@@ -14,9 +14,11 @@ The default values are `langflow` and `langflow`, respectively.
-## Generating an API Key
+## Generate an API key
-### Through Langflow UI
+Generate a user-specific token to use with Langflow.
+
+### Generate an API key with the Langflow UI
-
-Notice that editing variables in the chat interface take place temporarily and won’t change their original value in the components once the chat is closed.
-
-{" "}
-
-
-
-To view the complete prompt in its original, structured format, click the "Display Prompt" option. This feature lets you see the prompt exactly as it entered the model.
-
-{" "}
-
-
-In the chat interface, you can redefine which variable should be interpreted as the chat input. This gives you control over these inputs and allows dynamic and creative interactions.
-
-{" "}
-
diff --git a/docs/docs/administration/chat-widget.mdx b/docs/docs/administration/chat-widget.mdx
index 6d47e123b..0a6669cdd 100644
--- a/docs/docs/administration/chat-widget.mdx
+++ b/docs/docs/administration/chat-widget.mdx
@@ -61,7 +61,7 @@ import Admonition from "@theme/Admonition";
---
-### HTML
+### Embed your flow into HTML
The Chat Widget can be embedded into any HTML page, inside a _`
`_ tag, as demonstrated in the video below.
@@ -73,15 +73,15 @@ The Chat Widget can be embedded into any HTML page, inside a _``_ tag, as
---
-### React
+### Embed your flow with React
-To embed the Chat Widget using React, you'll need to insert this _`
```
-Then, declare your Web Component and encapsulate it in a React component.
+2. Declare your Web Component and encapsulate it in a React component.
```jsx
declare global {
@@ -106,28 +106,27 @@ export default function ChatWidget({ className }) {
}
```
-Finally, you can place the component anywhere in your code to display the Chat Widget.
+3. Finally, you can place the component anywhere in your code to display the Chat Widget.
---
-### Angular
+### Embed your flow with Angular
-To use it in Angular, first add this _`
```
-When you use a custom web component in an Angular template, the Angular compiler might show a warning when it doesn't recognize the custom elements by default. To suppress this warning, add _`CUSTOM_ELEMENTS_SCHEMA`_ to the module's _`@NgModule.schemas`_.
-
-- Open the module file (it typically ends with _.module.ts_) where you'd add the _`langflow-chat`_ web component.
-- Import _`CUSTOM_ELEMENTS_SCHEMA`_ at the top of the file:
+2. When you use a custom web component in an Angular template, the Angular compiler might show a warning when it doesn't recognize the custom elements by default. To suppress this warning, add _`CUSTOM_ELEMENTS_SCHEMA`_ to the module's _`@NgModule.schemas`_.
+3. Open the module file (it typically ends with _.module.ts_) where you'd add the _`langflow-chat`_ web component.
+4. Import _`CUSTOM_ELEMENTS_SCHEMA`_ at the top of the file:
```ts
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
```
-- Add _`CUSTOM_ELEMENTS_SCHEMA`_ to the 'schemas' array inside the '@NgModule' decorator:
+5. Add _`CUSTOM_ELEMENTS_SCHEMA`_ to the 'schemas' array inside the '@NgModule' decorator:
```ts
@NgModule({
@@ -142,9 +141,7 @@ import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
export class YourModule {}
```
-In your Angular project, find the component belonging to the module where _`CUSTOM_ELEMENTS_SCHEMA`_ was added.
-
-- Inside the template, add the _`langflow-chat`_ tag to include the Chat Widget in your component's view:
+6. In your Angular project, find the component belonging to the module where _`CUSTOM_ELEMENTS_SCHEMA`_ was added. Inside the template, add the _`langflow-chat`_ tag to include the Chat Widget in your component's view:
```jsx
| Prop | Type | Required | Description |
-| --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------- |
+| --------------------- | ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| bot_message_style | JSON | No | Applies custom formatting to bot messages. |
| chat_input_field | String | Yes | Defines the type of the input field for chat messages. |
| chat_inputs | JSON | Yes | Determines the chat input elements and their respective values. |
@@ -208,4 +205,4 @@ Use the widget API to customize your Chat Widget:
| tweaks | JSON | No | Applies additional custom adjustments for the associated flow. |
| user_message_style | JSON | No | Determines the formatting for user messages in the chat window. |
| width | Number | No | Sets the width of the chat window in pixels. |
-| window_title | String | No | Sets the title displayed in the chat window's header or title bar. | import ThemedImage from "@theme/ThemedImage"; |
+| window_title | String | No | Sets the title displayed in the chat window's header or title bar. |
diff --git a/docs/docs/administration/cli.mdx b/docs/docs/administration/cli.mdx
index 41bc76de3..9be0a3453 100644
--- a/docs/docs/administration/cli.mdx
+++ b/docs/docs/administration/cli.mdx
@@ -127,7 +127,7 @@ python -m langflow run
| `--backend-only` | This parameter, with a default value of `False`, allows running only the backend server without the frontend. It can also be set using the `LANGFLOW_BACKEND_ONLY` environment variable. For more, see [Backend-only](../deployment/backend-only.md). |
| `--store` | This parameter, with a default value of `True`, enables the store features, use `--no-store` to deactivate it. It can be configured using the `LANGFLOW_STORE` environment variable. |
-#### Environment Variables
+#### CLI environment variables
You can configure many of the CLI options using environment variables. These can be exported in your operating system or added to a `.env` file and loaded using the `--env-file` option.
diff --git a/docs/docs/administration/collection.mdx b/docs/docs/administration/collection.mdx
deleted file mode 100644
index c0616b2e2..000000000
--- a/docs/docs/administration/collection.mdx
+++ /dev/null
@@ -1,13 +0,0 @@
-import ThemedImage from '@theme/ThemedImage';
-import useBaseUrl from '@docusaurus/useBaseUrl';
-import ZoomableImage from '/src/theme/ZoomableImage.js';
-import ReactPlayer from 'react-player';
-
-# Collection
-
-A collection is a snapshot of the flows available in the database. You can download your entire collection for local storage and upload it anytime for future use.
-
-
-
-
diff --git a/docs/docs/administration/components.mdx b/docs/docs/administration/components.mdx
deleted file mode 100644
index 16aa83eff..000000000
--- a/docs/docs/administration/components.mdx
+++ /dev/null
@@ -1,58 +0,0 @@
-import ThemedImage from "@theme/ThemedImage";
-import useBaseUrl from "@docusaurus/useBaseUrl";
-import ZoomableImage from "/src/theme/ZoomableImage.js";
-import ReactPlayer from "react-player";
-
-# Component
-
-Components are the building blocks of the flows. They are made of inputs, outputs, and parameters that define their functionality, providing 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) section.
-
-### Component's Features
-
-
- During the flow creation process, you will notice handles (colored circles)
- attached to one or both sides of a component. These handles represent the
- availability to connect to other components, while their colors are type hints
- (hover over a handle to see connection details).
-
-
-
- For example, if you select a ConversationChain component, you
- will see orange o and purple{" "}
- o input handles. They indicate that
- this component accepts an LLM and a Memory component as inputs. The red
- asterisk * means that at least one input
- of that type is required.
-
-
-{" "}
-
-
-
-
- On the top right corner, you will find the component status icon 🔴. Make the
- necessary connections, build the flow (⚡ zap icon on the bottom right of the
- canvas) and once the validation is completed, the status of each validated
- component should light green 🟢. Hover over the component status to reveal the
- outputs going through it in case of success, or the detected error in case of
- failure.
-
-
----
-
-### Component's Parameters
-
-Langflow components can be edited in the component settings button. Hide parameters to reduce complexity and keep the canvas clean and intuitive for experimentation.
-
-
- When you click for New Project, you will see on the top left corner of the
- screen, some options such as Import, Export,{" "}
- Code and Save, as displayed in the image
- below:
-
-
-{" "}
-
-
-
-
- Further down, we will explain each of these options.
-
-
----
-
-### Import and Export
-
-Flows can be exported and imported as JSON files.
-
-
-Watch out for API keys being stored in local files.
-
-
-
----
-
-### Code
-
-The Code button shows snippets to use your flow as a Python object or an API.
-
-**Python Code**
-
-Through the Langflow package, you can run your flow from a JSON file. The example below shows how to run a flow from a JSON file.
-
-```python
-from langflow.load import run_flow_from_json
-
-results = run_flow_from_json("path/to/flow.json", input_value="Hello, World!")
-```
-
-**API**
-
-Once you save a flow, the API endpoint is created with your latest changes. Click the "code" button to use that flow as an API. You can post-adjust component parameters using the global variable TWEAKS.
-
-The example below shows a Python script making a POST request to a local API endpoint, which gets a prediction based on the message input.
-
-
-
-
-
-import ThemedImage from "@theme/ThemedImage";
-import useBaseUrl from "@docusaurus/useBaseUrl";
-import ZoomableImage from "/src/theme/ZoomableImage.js";
-import ReactPlayer from "react-player";
-import Admonition from "@theme/Admonition";
diff --git a/docs/docs/administration/global-env.mdx b/docs/docs/administration/global-env.mdx
index 51e5d633e..06ef488a8 100644
--- a/docs/docs/administration/global-env.mdx
+++ b/docs/docs/administration/global-env.mdx
@@ -8,7 +8,7 @@ import Admonition from "@theme/Admonition";
Global Variables are a useful feature of Langflow, allowing you to define reusable variables accessed from any Text field in your project.
-## TL;DR
+**TL;DR**
- Global Variables are reusable variables accessible from any Text field in your project.
- To create one, click the 🌐 button in a Text field and then **+ Add New Variable**.
@@ -17,7 +17,7 @@ Global Variables are a useful feature of Langflow, allowing you to define reusab
- All Credential Global Variables are encrypted and accessible only by you.
- Set _`LANGFLOW_STORE_ENVIRONMENT_VARIABLES`_ to _`true`_ in your `.env` file to add all variables in _`LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT`_ to your user's Global Variables.
-## Creating and Adding a Global Variable
+## Create and Add a Global Variable
To create and add a global variable, click the 🌐 button in a Text field, and then click **+ Add New Variable**.
@@ -59,7 +59,7 @@ For more on variables in HuggingFace Spaces, see [Managing Secrets](https://hugg
All Credential Global Variables are encrypted and accessible only by you.
-## Configuring Environment Variables in your .env file
+## Configure Environment Variables in your .env file
Setting `LANGFLOW_STORE_ENVIRONMENT_VARIABLES` to `true` in your `.env` file (default) adds all variables in `LANGFLOW_VARIABLES_TO_GET_FROM_ENVIRONMENT` to your user's Global Variables.
@@ -98,8 +98,6 @@ The default list of variables includes:
- VECTARA_CORPUS_ID
- VECTARA_API_KEY
-## Video
-
diff --git a/docs/docs/administration/login.mdx b/docs/docs/administration/login.mdx
index d5d7c1989..9f3c12cf9 100644
--- a/docs/docs/administration/login.mdx
+++ b/docs/docs/administration/login.mdx
@@ -6,11 +6,9 @@ import Admonition from "@theme/Admonition";
# Sign Up and Sign In
-## Introduction
-
The login functionality in Langflow serves to authenticate users and protect sensitive routes in the application. Starting from version 0.5, Langflow introduces an enhanced login mechanism that is governed by a few environment variables. This allows new secure features.
-## Environment Variables
+## Environment variables
The following environment variables are crucial in configuring the login settings:
@@ -68,7 +66,7 @@ export LANGFLOW_SECRET_KEY=randomly_generated_secure_key
By default, this variable is set to `False`. When enabled (`True`), new users are automatically activated and can log in without requiring explicit activation by the superuser.
-## Command-Line Interface
+## Manage superusers with the CLI
Langflow provides a command-line utility for managing superusers:
@@ -78,7 +76,7 @@ langflow superuser
This command prompts you to enter the username and password for the superuser, unless they are already set using environment variables.
-## Sign-up
+## Sign in
With _`LANGFLOW_AUTO_LOGIN`_ set to _`False`_, Langflow requires users to sign up before they can log in. The sign-up page is the default landing page when a user visits Langflow for the first time.
@@ -88,12 +86,12 @@ With _`LANGFLOW_AUTO_LOGIN`_ set to _`False`_, Langflow requires users to sign u
light: useBaseUrl("img/sign-up.png"),
dark: useBaseUrl("img/sign-up.png"),
}}
- style={{ width: "50%", maxWidth: "600px", margin: "0 auto" }}
+ style={{ width: "40%", margin: "20px auto" }}
/>
## Profile settings
-Users can change their profile settings by clicking on the profile icon in the top right corner of the application. This opens a dropdown menu with the following options:
+Once signed in, you can change your profile settings by clicking on the profile icon in the top right corner of the Langflow dashboard. This opens a dropdown menu with the following options:
- **Admin Page**: Opens the admin page, which is only accessible to the superuser.
- **Profile Settings**: Opens the profile settings page.
@@ -105,10 +103,10 @@ Users can change their profile settings by clicking on the profile icon in the t
light: useBaseUrl("img/my-account.png"),
dark: useBaseUrl("img/my-account.png"),
}}
- style={{ width: "50%", maxWidth: "600px", margin: "20px auto" }}
+ style={{ maxWidth: "600px", margin: "20px auto" }}
/>
-By clicking on **Profile Settings**, the user is taken to the profile settings page, where they can change their password and their profile picture.
+Select **Profile Settings** to change your password and your profile picture.
-By clicking on **Admin Page**, the superuser is taken to the admin page, where they
-can manage users and groups.
+Select **Admin Page** to manage users and groups as the superuser.
2. Chat with your bot as you normally would, all without having to open the editor.
-## Video
-
+
+## Playground I/O
+
+The Playground's appearance changes depending on what components are in your canvas.
+
+Adding or removing any of the below components modifies your Playground so you can monitor the inputs and outputs.
+
+- Chat Input
+- Text Input
+- Chat Output
+- Text Output
+- Records Output
+- Inspect Memory
+
+You can also select **Options** > **Logs** to see your flow's logs.
+
+For more information, see [Inputs and Outputs](../components/inputs-and-outputs.mdx).
diff --git a/docs/docs/components/agents.mdx b/docs/docs/components/agents.mdx
index cdc49a76d..00d597804 100644
--- a/docs/docs/components/agents.mdx
+++ b/docs/docs/components/agents.mdx
@@ -2,14 +2,6 @@ import Admonition from "@theme/Admonition";
# Agents
-
-
- We appreciate your understanding as we polish our documentation – it may
- contain some rough edges. Share your feedback or report issues to help us
- improve! 🛠️📝
-
-
-
Agents are components that use reasoning to make decisions and take actions, designed to autonomously perform tasks or provide services with some degree of agency. LLM chains can only perform hardcoded sequences of actions, while agents use LLMs to reason through which actions to take, and in which order.
---
diff --git a/docs/docs/components/chains.mdx b/docs/docs/components/chains.mdx
index 91477644d..a57f442e3 100644
--- a/docs/docs/components/chains.mdx
+++ b/docs/docs/components/chains.mdx
@@ -5,19 +5,11 @@ import Admonition from "@theme/Admonition";
# Chains
-
-
- Thank you for your patience while we enhance our documentation. It may have
- some imperfections. Share your feedback or report issues to help us improve!
- 🛠️📝
-
-
-
Chains, in the context of language models, refer to a series of calls made to a language model. This approach allows for using the output of one call as the input for another. Different chain types facilitate varying complexity levels, making them useful for creating pipelines and executing specific scenarios.
---
-### CombineDocsChain
+## CombineDocsChain
`CombineDocsChain` includes methods to combine or aggregate loaded documents for question-answering functionality.
@@ -34,7 +26,7 @@ Acts as a proxy for LangChain’s [documents](https://python.langchain.com/docs/
---
-### ConversationChain
+## ConversationChain
`ConversationChain` facilitates dynamic, interactive conversations with a language model, ideal for chatbots or virtual assistants.
@@ -48,7 +40,7 @@ Acts as a proxy for LangChain’s [documents](https://python.langchain.com/docs/
---
-### ConversationalRetrievalChain
+## ConversationalRetrievalChain
`ConversationalRetrievalChain` combines document search with question-answering capabilities, extracting information and providing answers.
diff --git a/docs/docs/components/custom.mdx b/docs/docs/components/custom.mdx
index 1c039bd2a..e17b9db8d 100644
--- a/docs/docs/components/custom.mdx
+++ b/docs/docs/components/custom.mdx
@@ -3,7 +3,7 @@ import Admonition from "@theme/Admonition";
# Custom Components
- Read the [Custom Component Guidelines](../administration/custom-component) for
+ Read the [Custom Component Tutorial](../tutorials/custom_components) for
detailed information on custom components.
diff --git a/docs/docs/components/experimental.mdx b/docs/docs/components/experimental.mdx
index 7664b0406..036fa334c 100644
--- a/docs/docs/components/experimental.mdx
+++ b/docs/docs/components/experimental.mdx
@@ -4,7 +4,9 @@ import Admonition from "@theme/Admonition";
Components in the experimental phase are currently in beta. They have been initially developed and tested but haven't yet achieved a stable or fully supported status. We encourage users to explore these components, provide feedback, and report any issues encountered.
-### Clear Message History Component
+---
+
+## Clear Message History Component
This component clears the message history for a specified session ID.
@@ -22,7 +24,7 @@ Provide the session ID to clear its message history.
---
-### Extract Key From Record
+## Extract Key From Record
This component extracts specified keys from a record.
@@ -49,7 +51,7 @@ Provide the record and specify the keys you want to extract. Optionally, enable
---
-### Flow as Tool
+## Flow as Tool
This component turns a function running a flow into a Tool.
@@ -84,7 +86,7 @@ Select a flow, name and describe the tool, and decide if you want to return the
---
-### Listen
+## Listen
This component listens for a specified notification.
@@ -100,7 +102,7 @@ Specify the notification to listen for.
---
-### List Flows
+## List Flows
This component lists all available flows.
@@ -110,7 +112,7 @@ Call this component without parameters to list all flows.
---
-### Merge Records
+## Merge Records
This component merges a list of records.
@@ -125,7 +127,7 @@ Provide the records you want to merge.
---
-### Notify
+## Notify
This component generates a notification.
@@ -151,7 +153,7 @@ Specify the notification name, provide a record if necessary, and indicate wheth
---
-### Run Flow
+## Run Flow
This component runs a specified flow.
@@ -179,7 +181,7 @@ Provide the input value, select the flow, and apply any tweaks.
---
-### Runnable Executor
+## Runnable Executor
This component executes a specified runnable.
@@ -210,7 +212,7 @@ Specify the input key, provide inputs, select the runnable, and optionally defin
---
-### SQL Executor
+## SQL Executor
This component executes an SQL query.
@@ -241,7 +243,7 @@ Provide the SQL query, specify the database URL, and configure settings for colu
---
-### SubFlow
+## SubFlow
This component dynamically generates a tool from a flow.
diff --git a/docs/docs/components/inputs-and-outputs.mdx b/docs/docs/components/inputs-and-outputs.mdx
index 2a624221a..484afc6b9 100644
--- a/docs/docs/components/inputs-and-outputs.mdx
+++ b/docs/docs/components/inputs-and-outputs.mdx
@@ -3,7 +3,7 @@ import ZoomableImage from "/src/theme/ZoomableImage.js";
# Inputs and Outputs
-TL;DR: Inputs and Outputs are a category of components that are used to define where data comes in and out of your flow.
+Inputs and Outputs are a category of components that are used to define where data comes in and out of your flow.
They also dynamically change the Playground and can be renamed to facilitate building and maintaining your flows.
## Inputs
@@ -20,6 +20,15 @@ You can find out more about Chat Input and other Inputs [here](#chat-input).
This component collects user input from the chat.
+
+
**Parameters**
- **Sender Type:** Specifies the sender type. Defaults to `User`. Options are `Machine` and `User`.
@@ -34,30 +43,30 @@ This component collects user input from the chat.
-
-
One significant capability of the Chat Input component is its ability to transform the Playground into a chat window. This feature is particularly valuable for scenarios requiring user input to initiate or influence the flow.
### Text Input
The **Text Input** component adds an **Input** field on the Playground. This enables you to define parameters while running and testing your flow.
+
+
**Parameters**
- **Value:** Specifies the text input value. This is where the user inputs text data that will be passed to the next component in the sequence. If no value is provided, it defaults to an empty string.
@@ -79,15 +88,6 @@ A template with `Name: {name}, Age: {age}` will convert the `Record` into a text
If you pass more than one `Record`, the text will be concatenated with a new line separator.
-
-
## Outputs
Outputs are components that are used to define where data comes out of your flow. They can be used to send data to the user, to the Playground, or to define how the data will be displayed in the Playground.
@@ -135,10 +135,6 @@ A prompt is the input provided to a language model, consisting of multiple compo
This component creates a prompt template with dynamic variables. This is useful for structuring prompts and passing dynamic data to a language model.
-**Parameters**
-
-- **Template:** The template for the prompt. This field allows you to create other fields dynamically by using curly brackets `{}`. For example, if you have a template like `Hello {name}, how are you?`, a new field called `name` will be created. Prompt variables can be created with any name inside curly brackets, e.g. `{variable_name}`.
-
+**Parameters**
+
+- **Template:** The template for the prompt. This field allows you to create other fields dynamically by using curly brackets `{}`. For example, if you have a template like `Hello {name}, how are you?`, a new field called `name` will be created. Prompt variables can be created with any name inside curly brackets, e.g. `{variable_name}`.
+
### PromptTemplate
The `PromptTemplate` component enables users to create prompts and define variables that control how the model is instructed. Users can input a set of variables which the template uses to generate the prompt when a conversation starts.
-
- After defining a variable in the prompt template, it acts as its own component
- input. See [Prompt Customization](../administration/prompt-customization) for
- more details.
-
+After defining a variable in the prompt template, it acts as its own component input. See [Prompt Customization](../administration/prompt-customization) for more details.
- **template:** The template used to format an individual request.
diff --git a/docs/docs/components/model_specs.mdx b/docs/docs/components/model_specs.mdx
index 9da89de3f..21ee1849b 100644
--- a/docs/docs/components/model_specs.mdx
+++ b/docs/docs/components/model_specs.mdx
@@ -2,19 +2,11 @@ import Admonition from "@theme/Admonition";
# Large Language Models (LLMs)
-
-
- Thank you for your patience as we refine our documentation. You might
- encounter some inconsistencies. Please help us improve by sharing your
- feedback or reporting any issues! 🛠️📝
-
-
-
A Large Language Model (LLM) is a foundational component of Langflow. It provides a uniform interface for interacting with LLMs from various providers, including OpenAI, Cohere, and HuggingFace. Langflow extensively uses LLMs across its chains and agents, employing them to generate text based on specific prompts or inputs.
---
-### Anthropic
+## Anthropic
This is a wrapper for Anthropic's large language models. Learn more at [Anthropic](https://www.anthropic.com).
@@ -24,7 +16,7 @@ This is a wrapper for Anthropic's large language models. Learn more at [Anthropi
---
-### ChatAnthropic
+## ChatAnthropic
This is a wrapper for Anthropic's large language model designed for chat-based interactions. Learn more at [Anthropic](https://www.anthropic.com).
@@ -34,7 +26,7 @@ This is a wrapper for Anthropic's large language model designed for chat-based i
---
-### CTransformers
+## CTransformers
`CTransformers` provides access to Transformer models implemented in C/C++ using the [GGML](https://github.com/ggerganov/ggml) library.
@@ -69,7 +61,7 @@ This is a wrapper for Anthropic's large language model designed for chat-based i
- **model_file**: The specific model file name within the repository or directory.
- **model_type**: The type of transformer model used. For further information, visit [ctransformers](https://github.com/marella/ctransformers).
-### ChatOpenAI Component
+## ChatOpenAI Component
This component interfaces with [OpenAI's](https://openai.com) large language models, supporting a variety of tasks such as chatbots, generative question-answering, and summarization.
@@ -80,7 +72,7 @@ This component interfaces with [OpenAI's](https://openai.com) large language mod
- **openai_api_key**: The API key required for authentication with the OpenAI API.
- **temperature**: Adjusts the randomness level of the text generation. This should be a non-negative number, defaulting to `0.7`.
-### Cohere Component
+## Cohere Component
A wrapper for accessing [Cohere's](https://cohere.com) large language models.
@@ -88,7 +80,7 @@ A wrapper for accessing [Cohere's](https://cohere.com) large language models.
- **max_tokens**: The limit on the number of tokens to generate per request, defaulting to `256`.
- **temperature**: Adjusts the randomness level in text generations. This should be a non-negative number, defaulting to `0.75`.
-### HuggingFaceHub Component
+## HuggingFaceHub Component
A component facilitating access to models hosted on the [HuggingFace Hub](https://www.huggingface.co/models).
@@ -97,7 +89,7 @@ A component facilitating access to models hosted on the [HuggingFace Hub](https:
- **repo_id**: Specifies the model repository, defaulting to `gpt2`.
- **task**: The specific task to execute with the model, returning either `generated_text` or `summary_text`.
-### LlamaCpp Component
+## LlamaCpp Component
This component provides access to `llama.cpp` models, ensuring high performance and flexibility.
@@ -126,7 +118,7 @@ This component provides access to `llama.cpp` models, ensuring high performance
- **verbose**: Controls the verbosity of output details. When enabled, it provides insights into internal states to aid debugging and understanding, defaulting to `False`.
- **vocab_only**: Loads only the vocabulary without model weights, defaulting to `False`.
-### VertexAI Component
+## VertexAI Component
This component integrates with [Google Vertex AI](https://cloud.google.com/vertex-ai) large language models to enhance AI capabilities.
diff --git a/docs/docs/components/models.mdx b/docs/docs/components/models.mdx
index fc6d7924e..f02c1654b 100644
--- a/docs/docs/components/models.mdx
+++ b/docs/docs/components/models.mdx
@@ -2,7 +2,7 @@ import Admonition from "@theme/Admonition";
# Models
-### Amazon Bedrock
+## Amazon Bedrock
This component facilitates the generation of text using the LLM (Large Language Model) model from Amazon Bedrock.
@@ -48,7 +48,7 @@ This component facilitates the generation of text using the LLM (Large Language
---
-### Anthropic
+## Anthropic
This component allows the generation of text using Anthropic Chat&Completion large language models.
@@ -79,7 +79,7 @@ For detailed documentation and integration guides, please refer to the [Anthropi
---
-### Azure OpenAI
+## Azure OpenAI
This component allows the generation of text using the LLM (Large Language Model) model from Azure OpenAI.
@@ -124,7 +124,7 @@ For detailed documentation and integration guides, please refer to the [Azure Op
---
-### Cohere
+## Cohere
This component enables text generation using Cohere large language models.
@@ -144,7 +144,7 @@ This component enables text generation using Cohere large language models.
---
-### Google Generative AI
+## Google Generative AI
This component enables text generation using Google Generative AI.
@@ -172,7 +172,7 @@ This component enables text generation using Google Generative AI.
---
-### Hugging Face API
+## Hugging Face API
This component facilitates text generation using LLM models from the Hugging Face Inference API.
@@ -194,7 +194,7 @@ This component facilitates text generation using LLM models from the Hugging Fac
---
-### LiteLLM Model
+## LiteLLM Model
Generates text using the `LiteLLM` collection of large language models.
@@ -217,7 +217,7 @@ Generates text using the `LiteLLM` collection of large language models.
---
-### Ollama
+## Ollama
Generate text using Ollama Local LLMs.
@@ -252,7 +252,7 @@ Generate text using Ollama Local LLMs.
---
-### OpenAI
+## OpenAI
This component facilitates text generation using OpenAI's models.
@@ -278,7 +278,7 @@ This component facilitates text generation using OpenAI's models.
---
-### Qianfan
+## Qianfan
This component facilitates the generation of text using Baidu Qianfan chat models.
@@ -317,7 +317,7 @@ This component facilitates the generation of text using Baidu Qianfan chat model
---
-### Vertex AI
+## Vertex AI
The `ChatVertexAI` is a component for generating text using Vertex AI Chat large language models API.
diff --git a/docs/docs/components/retrievers.mdx b/docs/docs/components/retrievers.mdx
index f86695e37..792b9e20b 100644
--- a/docs/docs/components/retrievers.mdx
+++ b/docs/docs/components/retrievers.mdx
@@ -2,19 +2,11 @@ import Admonition from "@theme/Admonition";
# Retrievers
-
-
- We appreciate your patience as we enhance our documentation. It may have
- some imperfections. Please share your feedback or report issues to help us
- improve. 🛠️📝
-
-
-
A retriever is an interface that returns documents in response to an unstructured query. It's broader than a vector store because it doesn't need to store documents; it only needs to retrieve them.
---
-### MultiQueryRetriever
+## MultiQueryRetriever
The `MultiQueryRetriever` automates generating multiple queries, retrieves relevant documents for each query, and aggregates the results. This method improves retrieval effectiveness and addresses the limitations of traditional distance-based methods.
diff --git a/docs/docs/components/text-splitters.mdx b/docs/docs/components/text-splitters.mdx
index 6e3925ee2..02e7a311b 100644
--- a/docs/docs/components/text-splitters.mdx
+++ b/docs/docs/components/text-splitters.mdx
@@ -2,19 +2,11 @@ import Admonition from "@theme/Admonition";
# Text Splitters
-
-
- Thank you for your patience as we enhance our documentation. It might
- currently have some rough edges. Please share your feedback or report any
- issues to assist us in improving! 🛠️📝
-
-
-
A text splitter is a tool that divides a document or text into smaller chunks or segments. This helps make large texts more manageable for analysis or processing.
---
-### CharacterTextSplitter
+## CharacterTextSplitter
The `CharacterTextSplitter` splits a long text into smaller chunks based on a specified character. It aims to keep paragraphs, sentences, and words intact as much as possible since these are semantically related elements of text.
@@ -27,7 +19,7 @@ The `CharacterTextSplitter` splits a long text into smaller chunks based on a sp
---
-### RecursiveCharacterTextSplitter
+## RecursiveCharacterTextSplitter
The `RecursiveCharacterTextSplitter` functions similarly to the `CharacterTextSplitter` by trying to keep paragraphs, sentences, and words together. It also recursively splits the text into smaller chunks if the initial chunk size exceeds a specified threshold.
@@ -38,7 +30,7 @@ The `RecursiveCharacterTextSplitter` functions similarly to the `CharacterTextSp
- **chunk_size:** The maximum number of characters in each chunk.
- **separators:** A list of characters used to split the text into chunks. The splitter first tries to split text using the first character in the `separators` list. If any chunk exceeds the maximum size, it proceeds to the next character in the list and continues splitting. The defaults are ["\n\n", "\n", " ", ""].
-### LanguageRecursiveTextSplitter
+## LanguageRecursiveTextSplitter
The `LanguageRecursiveTextSplitter` divides text into smaller chunks based on the programming language of the text.
diff --git a/docs/docs/components/tools.mdx b/docs/docs/components/tools.mdx
index 25d458360..6460db860 100644
--- a/docs/docs/components/tools.mdx
+++ b/docs/docs/components/tools.mdx
@@ -2,72 +2,64 @@ import Admonition from "@theme/Admonition";
# Tools
-
-
- Thanks for your patience as we refine our documentation. It might have some
- rough edges currently. Please share your feedback or report issues to help
- us enhance it! 🛠️📝
-
-
-
-### SearchApi
+## SearchApi
SearchApi offers a real-time search engine results API that returns structured JSON data, including answer boxes, knowledge graphs, organic results, and more.
-#### Parameters
+### Parameters
- **Api Key:** A unique identifier required for authentication with real-time search engines, obtainable through the [SearchApi dashboard](https://www.searchapi.io/).
- **Engine:** Specifies the search engine used, such as Google, Google Scholar, Bing, YouTube, and YouTube transcripts. Refer to the [documentation](https://www.searchapi.io/docs/google) for a complete list of supported engines.
- **Parameters:** Allows the selection of various parameters recognized by SearchApi. Some parameters are mandatory while others are optional.
-#### Output
+### Output
- **Document:** The JSON response from the request.
-### BingSearchRun
+## BingSearchRun
Bing Search, a web search engine by Microsoft, provides search results for various content types like web pages, images, videos, and news articles. It combines algorithms and human editors to deliver these results.
-#### Parameters
+### Parameters
- **Api Wrapper:** A BingSearchAPIWrapper component that processes the search URL and subscription key.
-### Calculator
+## Calculator
The calculator tool leverages an LLMMathChain to provide mathematical calculation capabilities, enabling the agent to perform computations as needed.
-#### Parameters
+### Parameters
- **LLM:** The Language Model used for calculations.
-### GoogleSearchResults
+## GoogleSearchResults
This is a wrapper around Google Search tailored for users who need precise control over the JSON data returned from the API.
-#### Parameters
+### Parameters
- **Api Wrapper:** A GoogleSearchAPIWrapper equipped with a Google API key and CSE ID.
-### GoogleSearchRun
+## GoogleSearchRun
This tool acts as a quick wrapper around Google Search, executing the search query and returning the snippet from the most relevant result.
-#### Parameters
+### Parameters
- **Api Wrapper:** A GoogleSearchAPIWrapper equipped with a Google API key and CSE ID.
-### GoogleSerperRun
+## GoogleSerperRun
A cost-effective Google Search API.
-#### Parameters
+### Parameters
- **Api Wrapper:** A GoogleSerperAPIWrapper with the required API key and result keys.
-### InfoSQLDatabaseTool
+## InfoSQLDatabaseTool
This tool retrieves metadata about SQL databases. It takes a comma-separated list of table names as input and outputs the schema and sample rows for those tables.
-#### Parameters
+### Parameters
- **Db:** The SQL database to query.
diff --git a/docs/docs/components/utilities.mdx b/docs/docs/components/utilities.mdx
index 8ef1f91c8..44263f583 100644
--- a/docs/docs/components/utilities.mdx
+++ b/docs/docs/components/utilities.mdx
@@ -2,17 +2,11 @@ import Admonition from "@theme/Admonition";
# Utilities
-
- We appreciate your understanding as we polish our documentation—it may contain
- some rough edges. Share your feedback or report issues to help us improve!
- 🛠️📝
-
-
Utilities are a set of actions that can be used to perform common tasks in a flow. They are available in the **Utilities** section in the sidebar.
---
-### GET request
+## GET request
Make a GET request to the specified URL.
@@ -27,7 +21,7 @@ Make a GET request to the specified URL.
---
-### POST request
+## POST request
Make a POST request to the specified URL.
@@ -43,7 +37,7 @@ Make a POST request to the specified URL.
---
-### Update request
+## Update request
Make a PATCH or PUT request to the specified URL.
@@ -60,7 +54,7 @@ Make a PATCH or PUT request to the specified URL.
---
-### JSON document builder
+## JSON document builder
Build a document containing a JSON object using a key and another document page content.
diff --git a/docs/docs/contributing/how-contribute.md b/docs/docs/contributing/how-contribute.md
index 4939edaee..ba9223fec 100644
--- a/docs/docs/contributing/how-contribute.md
+++ b/docs/docs/contributing/how-contribute.md
@@ -1,4 +1,4 @@
-# How to contribute?
+# How to Contribute?
👋 Hello there! We welcome contributions from developers of all levels to our open-source project on [GitHub](https://github.com/langflow-ai/langflow). If you'd like to contribute, please check our contributing guidelines and help make Langflow more accessible.
diff --git a/docs/docs/deployment/docker.md b/docs/docs/deployment/docker.md
index 1ebb5746e..a8864db55 100644
--- a/docs/docs/deployment/docker.md
+++ b/docs/docs/deployment/docker.md
@@ -7,7 +7,7 @@ This guide will help you get LangFlow up and running using Docker and Docker Com
- Docker
- Docker Compose
-## Steps
+## Clone repo and build Docker container
1. Clone the LangFlow repository:
@@ -29,11 +29,11 @@ This guide will help you get LangFlow up and running using Docker and Docker Com
LangFlow will now be accessible at [http://localhost:7860/](http://localhost:7860/).
-## Docker Compose Configuration
+## Docker Compose configuration
The Docker Compose configuration spins up two services: `langflow` and `postgres`.
-### LangFlow Service
+### LangFlow service
The `langflow` service uses the `langflowai/langflow:latest` Docker image and exposes port 7860. It depends on the `postgres` service.
@@ -46,7 +46,7 @@ Volumes:
- `langflow-data`: This volume is mapped to `/var/lib/langflow` in the container.
-### PostgreSQL Service
+### PostgreSQL service
The `postgres` service uses the `postgres:16` Docker image and exposes port 5432.
@@ -60,6 +60,6 @@ Volumes:
- `langflow-postgres`: This volume is mapped to `/var/lib/postgresql/data` in the container.
-## Switching to a Specific LangFlow Version
+## Switch to a specific LangFlow version
If you want to use a specific version of LangFlow, you can modify the `image` field under the `langflow` service in the Docker Compose file. For example, to use version 1.0-alpha, change `langflowai/langflow:latest` to `langflowai/langflow:1.0-alpha`.
diff --git a/docs/docs/getting-started/canvas.mdx b/docs/docs/getting-started/canvas.mdx
index 5974f245b..d54ffeeb4 100644
--- a/docs/docs/getting-started/canvas.mdx
+++ b/docs/docs/getting-started/canvas.mdx
@@ -11,15 +11,6 @@ The **Langflow canvas** is the central hub of Langflow, where you'll assemble ne
To get a feel for the canvas, we'll examine a basic prompting flow.
You can either build this flow yourself, or select **New Project** > **Basic prompting** to open a canvas with the flow pre-built.
-
-
## Flows, components, collections, and projects
A [flow](#flow) is a pipeline of components connected together in the Langflow canvas.
@@ -44,7 +35,7 @@ For example, the [Basic prompting](../starter-projects/basic-prompting.mdx) flow
light: "img/basic-prompting.png",
dark: "img/basic-prompting.png",
}}
- style={{ width: "80%", margin: "20px auto" }}
+ style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
/>
In this flow, 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.
@@ -77,7 +68,7 @@ Components are the building blocks of flows. They consist of inputs, outputs, an
light: useBaseUrl("img/single-component.png"),
dark: useBaseUrl("img/single-component.png"),
}}
- style={{ width: "50%", maxWidth: "800px", margin: "20px auto" }}
+ style={{ width: "40%", margin: "20px auto" }}
/>
@@ -112,7 +103,7 @@ The menu options are **Code**, **Save**, **Duplicate**, and **More**.
light: "img/chat-input-with-menu.png",
dark: "img/chat-input-with-menu.png",
}}
- style={{ width: "30%", margin: "20px auto" }}
+ style={{ width: "40%", margin: "20px auto" }}
/>
### Code menu
@@ -174,13 +165,14 @@ Modify the call's parameters in the **Tweaks** window, click the **Copy Code** o
light: "img/api-window.png",
dark: "img/api-window.png",
}}
- style={{ width: "50%", margin: "20px auto" }}
+ style={{ width: "60%", margin: "20px auto" }}
/>
### curl
The **curl** tab displays sample code for posting a query to your flow.
Modify the `input_value` to change your input message.
+Copy the code and run it to post a query to your flow and get the result.
```curl
curl -X POST \
diff --git a/docs/docs/getting-started/flows-components-collections.mdx b/docs/docs/getting-started/flows-components-collections.mdx
deleted file mode 100644
index 335fb5c12..000000000
--- a/docs/docs/getting-started/flows-components-collections.mdx
+++ /dev/null
@@ -1,20 +0,0 @@
-import ThemedImage from "@theme/ThemedImage";
-import useBaseUrl from "@docusaurus/useBaseUrl";
-import ZoomableImage from "/src/theme/ZoomableImage.js";
-import ReactPlayer from "react-player";
-
-# 🖥️ Flows, components, collections, and projects
-
-## TL;DR
-
-A [flow](#flow) is a pipeline of components connected together in the Langflow canvas.
-
-A [component](#component) is a single building block within a flow. A component has inputs, outputs, and parameters that define its functionality.
-
-A [collection](#collection) is a snapshot of the flows available in your database. Collections can be downloaded to local storage and uploaded for future use.
-
-A [project](#project) can be a component or a flow. Projects are saved as part of your collection.
-
-For example, the **OpenAI LLM** is a **component** of the **Basic prompting** flow, and the **flow** is stored in a **collection**.
-
-## Component
diff --git a/docs/docs/getting-started/install-langflow.mdx b/docs/docs/getting-started/install-langflow.mdx
index 4beb5e362..643938beb 100644
--- a/docs/docs/getting-started/install-langflow.mdx
+++ b/docs/docs/getting-started/install-langflow.mdx
@@ -6,13 +6,10 @@ import Admonition from "@theme/Admonition";
# 📦 Install Langflow
- 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 version 3.10 or greater.
-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.
+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.
Install Langflow with pip:
@@ -89,7 +86,7 @@ You'll be presented with the following screen:
light: "img/duplicate-space.png",
dark: "img/duplicate-space.png",
}}
- style={{ width: "100%", margin: "20px auto" }}
+ style={{ width: "80%", maxWidth: "800px", margin: "0 auto" }}
/>
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!
diff --git a/docs/docs/getting-started/quickstart.mdx b/docs/docs/getting-started/quickstart.mdx
index 3f02db27f..544b29b18 100644
--- a/docs/docs/getting-started/quickstart.mdx
+++ b/docs/docs/getting-started/quickstart.mdx
@@ -10,6 +10,8 @@ This guide demonstrates how to build a basic prompt flow and modify that prompt
## Prerequisites
+- [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/)
+
- [Langflow installed and running](./install-langflow.mdx)
- [OpenAI API key](https://platform.openai.com)
diff --git a/docs/docs/migration/migrating-to-one-point-zero.mdx b/docs/docs/migration/migrating-to-one-point-zero.mdx
index 973393606..e58620347 100644
--- a/docs/docs/migration/migrating-to-one-point-zero.mdx
+++ b/docs/docs/migration/migrating-to-one-point-zero.mdx
@@ -2,15 +2,6 @@ import Admonition from "@theme/Admonition";
# Migrating to Langflow 1.0: A Guide
-
-
- We are currently working on updating this guide to provide the most accurate
- and up-to-date information on migrating to Langflow 1.0. We will be adding
- more content and examples to help you navigate the changes and improvements
- in the new version.
-
-
-
Langflow 1.0 is a significant update that brings many exciting changes and improvements to the platform.
This guide will walk you through the key improvements and help you migrate your existing projects to the new version.
diff --git a/docs/docs/migration/possible-installation-issues.mdx b/docs/docs/migration/possible-installation-issues.mdx
index a012a1c09..203996f39 100644
--- a/docs/docs/migration/possible-installation-issues.mdx
+++ b/docs/docs/migration/possible-installation-issues.mdx
@@ -4,14 +4,10 @@ This is a list of possible issues that you may encounter when installing Langflo
## _`No module named 'langflow.__main__'`_
-### TL;DR
-
1. Run _`python -m langflow run`_ instead of _`langflow run`_.
2. If that doesn't work, reinstall Langflow with _`_python -m pip install langflow --pre -U`_.
3. If that doesn't work, reinstall Langflow and its dependencies with _`python -m pip install langflow --pre -U --force-reinstall`_.
-### Details
-
When you try to run Langflow using the command `langflow run`, you may encounter the following error:
```bash
@@ -33,14 +29,12 @@ There are two possible reasons for this error:
## _`Something went wrong running migrations. Please, run 'langflow migration --fix'`_
-### TL;DR
+Clear the cache by deleting the contents of the cache folder.
-- Clear the cache by deleting the contents of the cache folder.
- This folder can be found at:
- - **Linux or WSL2 on Windows**: `home//.cache/langflow/`
- - **MacOS**: `/Users//Library/Caches/langflow/`
+This folder can be found at:
-### Details
+- **Linux or WSL2 on Windows**: `home//.cache/langflow/`
+- **MacOS**: `/Users//Library/Caches/langflow/`
This error can occur during Langflow upgrades when the new version can't override `langflow-pre.db` in `.cache/langflow/`. Clearing the cache removes this file but will also erase your settings.
diff --git a/docs/docs/starter-projects/document-qa.mdx b/docs/docs/starter-projects/document-qa.mdx
index ddbcd901a..f3c4f0a0a 100644
--- a/docs/docs/starter-projects/document-qa.mdx
+++ b/docs/docs/starter-projects/document-qa.mdx
@@ -33,7 +33,7 @@ Build a question-and-answer chatbot with a document loaded from local memory.
light: "img/document-qa.png",
dark: "img/document-qa.png",
}}
- style={{ width: "80%", margin: "20px auto" }}
+ style={{ width: "100%", maxWidth: "800px", margin: "0 auto" }}
/>
This flow creates a basic chatbot with the **Chat Input**, **Prompt**, **OpenAI**, and **Chat Output** components.
diff --git a/docs/docs/tutorials/chatprompttemplate_guide.mdx b/docs/docs/tutorials/chatprompttemplate_guide.mdx
index 48059b134..a01fec1ca 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
+# Build Chatbots with the System Message Component
## Overview
diff --git a/docs/docs/administration/custom-component.mdx b/docs/docs/tutorials/custom_components.mdx
similarity index 99%
rename from docs/docs/administration/custom-component.mdx
rename to docs/docs/tutorials/custom_components.mdx
index 02a137d07..110e5dbc7 100644
--- a/docs/docs/administration/custom-component.mdx
+++ b/docs/docs/tutorials/custom_components.mdx
@@ -14,7 +14,7 @@ A Custom Component is created from a user-defined Python script that uses the _`
Let's take a look at the basic rules and features. Then we'll go over an example.
-## TL;DR
+**TL;DR**
- Create a class that inherits from _`CustomComponent`_ and contains a _`build`_ method.
- Use arguments with [Type Annotations (or Type Hints)](https://docs.python.org/3/library/typing.html) of the _`build`_ method to create component fields.
@@ -355,7 +355,7 @@ All done! This is what our script and brand-new custom component look like:
---
-## Loading Custom Components
+## Load Custom Components
For advanced customization, Langflow offers the option to create and load custom components outside of the standard interface. This process involves creating the desired components using a text editor and loading them using the Langflow CLI.
@@ -380,7 +380,7 @@ Your structure should look something like this:
└── ...
```
-### Loading Custom Components
+### Load Custom Components
The recommended way to load custom components is to set the _`LANGFLOW_COMPONENTS_PATH`_ environment variable to the path of your custom components directory. Then, run the Langflow CLI as usual.
@@ -397,7 +397,7 @@ langflow run --components-path /path/to/components
Langflow will attempt to load all of the components found in the specified directory. If a component fails to load due to errors in the component's code, Langflow will print an error message to the console but will continue loading the rest of the components.
-### Interacting with Custom Components
+### Interact with Custom Components
Once your custom components have been loaded successfully, they will appear in Langflow's sidebar. From there, you can add them to your Langflow canvas for use. However, please note that components with errors will not be available for addition to the canvas. Always ensure your code is error-free before attempting to load components.
diff --git a/docs/docs/tutorials/loading_document.mdx b/docs/docs/tutorials/loading_document.mdx
index 4a6143a0e..c123624c1 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
+# Integrate Documents with Prompt Variables
## Overview
diff --git a/docs/docs/tutorials/rag-with-astradb.mdx b/docs/docs/tutorials/rag-with-astradb.mdx
index 9bb813f55..54c63cfa1 100644
--- a/docs/docs/tutorials/rag-with-astradb.mdx
+++ b/docs/docs/tutorials/rag-with-astradb.mdx
@@ -13,7 +13,8 @@ In this guide, we will use Astra DB as a vector store to store and retrieve the
This guide assumes that you have Langflow up and running. If you are new to
- Langflow, you can check out the [Getting Started](/) guide.
+ Langflow, you can check out the [Getting
+ Started](../getting-started/install-langflow.mdx) guide.
TLDR;
@@ -75,9 +76,11 @@ Now we are all set to start building our RAG application using Astra DB and Lang
If you haven't already, now is the time to launch Langflow. To make things easier, you can duplicate our [Langflow 1.0 Space](https://huggingface.co/spaces/Langflow/Langflow-Preview?duplicate=true) which sets up a Langflow instance just for you.
-## Open the Vector Store RAG Project
+## Open the Vector Store RAG Project in Langflow
-To get started, click on the **New Project** button and look for the **Vector Store RAG** project. This will open a starter project with the necessary components to run a RAG application using Astra DB.
+Run Langflow and open the UI.
+
+In the Langflow dashboard, click the **New Project** button and select the **Vector Store RAG** project. This will open a starter project with the necessary components to run a RAG application using Astra DB.
This project consists of two flows. The simpler one is the **Ingestion Flow** which is responsible for ingesting the documents into the Astra DB database.
diff --git a/docs/docs/whats-new/customization-control.mdx b/docs/docs/whats-new/customization-control.mdx
deleted file mode 100644
index 11f23f53c..000000000
--- a/docs/docs/whats-new/customization-control.mdx
+++ /dev/null
@@ -1 +0,0 @@
-# A New Customization and Control
\ No newline at end of file
diff --git a/docs/docs/whats-new/debugging-reimagined.mdx b/docs/docs/whats-new/debugging-reimagined.mdx
deleted file mode 100644
index d30234088..000000000
--- a/docs/docs/whats-new/debugging-reimagined.mdx
+++ /dev/null
@@ -1 +0,0 @@
-# Debugging Reimagined
\ No newline at end of file
diff --git a/docs/docs/whats-new/simplification-standardization.mdx b/docs/docs/whats-new/simplification-standardization.mdx
deleted file mode 100644
index f7e3115bc..000000000
--- a/docs/docs/whats-new/simplification-standardization.mdx
+++ /dev/null
@@ -1 +0,0 @@
-# Simplification Through Standardization
\ No newline at end of file
diff --git a/docs/sidebars.js b/docs/sidebars.js
index 04d81d475..a0d9e2d7d 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -105,6 +105,7 @@ module.exports = {
collapsed: true,
items: [
"tutorials/chatprompttemplate_guide",
+ "tutorials/custom_components",
"tutorials/loading_document",
"tutorials/rag-with-astradb",
],
diff --git a/poetry.lock b/poetry.lock
index 67ba34d2b..2f3ec531b 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand.
[[package]]
name = "aiohttp"
@@ -1548,6 +1548,24 @@ files = [
{file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
]
+[[package]]
+name = "deepdiff"
+version = "7.0.1"
+description = "Deep Difference and Search of any Python object/data. Recreate objects by adding adding deltas to each other."
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "deepdiff-7.0.1-py3-none-any.whl", hash = "sha256:447760081918216aa4fd4ca78a4b6a848b81307b2ea94c810255334b759e1dc3"},
+ {file = "deepdiff-7.0.1.tar.gz", hash = "sha256:260c16f052d4badbf60351b4f77e8390bee03a0b516246f6839bc813fb429ddf"},
+]
+
+[package.dependencies]
+ordered-set = ">=4.1.0,<4.2.0"
+
+[package.extras]
+cli = ["click (==8.1.7)", "pyyaml (==6.0.1)"]
+optimize = ["orjson"]
+
[[package]]
name = "defusedxml"
version = "0.7.1"
@@ -2088,6 +2106,17 @@ docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1
testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8.0.1)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"]
typing = ["typing-extensions (>=4.8)"]
+[[package]]
+name = "filetype"
+version = "1.2.0"
+description = "Infer file type and MIME type of any file/buffer. No external dependencies."
+optional = false
+python-versions = "*"
+files = [
+ {file = "filetype-1.2.0-py2.py3-none-any.whl", hash = "sha256:7ce71b6880181241cf7ac8697a2f1eb6a8bd9b429f7ad6d27b8db9ba5f1c2d25"},
+ {file = "filetype-1.2.0.tar.gz", hash = "sha256:66b56cd6474bf41d8c54660347d37afcc3f7d1970648de365c102ef77548aadb"},
+]
+
[[package]]
name = "flaml"
version = "2.1.2"
@@ -3929,6 +3958,17 @@ files = [
[package.dependencies]
jsonpointer = ">=1.9"
+[[package]]
+name = "jsonpath-python"
+version = "1.0.6"
+description = "A more powerful JSONPath implementation in modern python"
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "jsonpath-python-1.0.6.tar.gz", hash = "sha256:dd5be4a72d8a2995c3f583cf82bf3cd1a9544cfdabf2d22595b67aff07349666"},
+ {file = "jsonpath_python-1.0.6-py3-none-any.whl", hash = "sha256:1e3b78df579f5efc23565293612decee04214609208a2335884b3ee3f786b575"},
+]
+
[[package]]
name = "jsonpointer"
version = "2.4"
@@ -4321,6 +4361,20 @@ files = [
requests = ">=2,<3"
types-requests = ">=2.31.0.2,<3.0.0.0"
+[[package]]
+name = "langdetect"
+version = "1.0.9"
+description = "Language detection library ported from Google's language-detection."
+optional = false
+python-versions = "*"
+files = [
+ {file = "langdetect-1.0.9-py2-none-any.whl", hash = "sha256:7cbc0746252f19e76f77c0b1690aadf01963be835ef0cd4b56dddf2a8f1dfc2a"},
+ {file = "langdetect-1.0.9.tar.gz", hash = "sha256:cbc1fef89f8d062739774bd51eda3da3274006b3661d199c2655f6b3f6d605a0"},
+]
+
+[package.dependencies]
+six = "*"
+
[[package]]
name = "langflow-base"
version = "0.0.60"
@@ -4446,12 +4500,12 @@ proxy = ["PyJWT (>=2.8.0,<3.0.0)", "apscheduler (>=3.10.4,<4.0.0)", "backoff", "
[[package]]
name = "llama-cpp-python"
-version = "0.2.77"
+version = "0.2.78"
description = "Python bindings for the llama.cpp library"
optional = true
python-versions = ">=3.8"
files = [
- {file = "llama_cpp_python-0.2.77.tar.gz", hash = "sha256:5d2f87df941a72ad6d122c3ffd91d8fe58542db350bd169c07b025d625a26803"},
+ {file = "llama_cpp_python-0.2.78.tar.gz", hash = "sha256:3df7cfde84287faaf29675fba8939060c3ab3f0ce8db875dabf7df5d83bd8751"},
]
[package.dependencies]
@@ -5288,6 +5342,31 @@ doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-t
extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"]
test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"]
+[[package]]
+name = "nltk"
+version = "3.8.1"
+description = "Natural Language Toolkit"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "nltk-3.8.1-py3-none-any.whl", hash = "sha256:fd5c9109f976fa86bcadba8f91e47f5e9293bd034474752e92a520f81c93dda5"},
+ {file = "nltk-3.8.1.zip", hash = "sha256:1834da3d0682cba4f2cede2f9aad6b0fafb6461ba451db0efb6f9c39798d64d3"},
+]
+
+[package.dependencies]
+click = "*"
+joblib = "*"
+regex = ">=2021.8.3"
+tqdm = "*"
+
+[package.extras]
+all = ["matplotlib", "numpy", "pyparsing", "python-crfsuite", "requests", "scikit-learn", "scipy", "twython"]
+corenlp = ["requests"]
+machine-learning = ["numpy", "python-crfsuite", "scikit-learn", "scipy"]
+plot = ["matplotlib"]
+tgrep = ["pyparsing"]
+twitter = ["twython"]
+
[[package]]
name = "nodeenv"
version = "1.9.1"
@@ -5797,6 +5876,20 @@ document = ["ase", "cmaes (>=0.10.0)", "fvcore", "lightgbm", "matplotlib (!=3.6.
optional = ["boto3", "cmaes (>=0.10.0)", "google-cloud-storage", "matplotlib (!=3.6.0)", "pandas", "plotly (>=4.9.0)", "redis", "scikit-learn (>=0.24.2)", "scipy", "torch"]
test = ["coverage", "fakeredis[lua]", "kaleido", "moto", "pytest", "scipy (>=1.9.2)", "torch"]
+[[package]]
+name = "ordered-set"
+version = "4.1.0"
+description = "An OrderedSet is a custom MutableSet that remembers its order, so that every"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"},
+ {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"},
+]
+
+[package.extras]
+dev = ["black", "mypy", "pytest"]
+
[[package]]
name = "orjson"
version = "3.10.0"
@@ -6261,13 +6354,13 @@ twisted = ["twisted"]
[[package]]
name = "prompt-toolkit"
-version = "3.0.46"
+version = "3.0.47"
description = "Library for building powerful interactive command lines in Python"
optional = false
python-versions = ">=3.7.0"
files = [
- {file = "prompt_toolkit-3.0.46-py3-none-any.whl", hash = "sha256:45abe60a8300f3c618b23c16c4bb98c6fc80af8ce8b17c7ae92db48db3ee63c1"},
- {file = "prompt_toolkit-3.0.46.tar.gz", hash = "sha256:869c50d682152336e23c4db7f74667639b5047494202ffe7670817053fd57795"},
+ {file = "prompt_toolkit-3.0.47-py3-none-any.whl", hash = "sha256:0d7bfa67001d5e39d02c224b663abc33687405033a8c422d0d675a5a13361d10"},
+ {file = "prompt_toolkit-3.0.47.tar.gz", hash = "sha256:1e1b29cb58080b1e69f207c893a1a7bf16d127a5c30c9d17a25a5d77792e5360"},
]
[package.dependencies]
@@ -7239,6 +7332,20 @@ asyncio-client = ["aiohttp (>=3.4)"]
client = ["requests (>=2.21.0)", "websocket-client (>=0.54.0)"]
docs = ["sphinx"]
+[[package]]
+name = "python-iso639"
+version = "2024.4.27"
+description = "ISO 639 language codes, names, and other associated information"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "python_iso639-2024.4.27-py3-none-any.whl", hash = "sha256:27526a84cebc4c4d53fea9d1ebbc7209c8d279bebaa343e6765a1fc8780565ab"},
+ {file = "python_iso639-2024.4.27.tar.gz", hash = "sha256:97e63b5603e085c6a56a12a95740010e75d9134e0aab767e0978b53fd8824f13"},
+]
+
+[package.extras]
+dev = ["black (==24.4.2)", "build (==1.2.1)", "flake8 (==7.0.0)", "pytest (==8.1.2)", "requests (==2.31.0)", "twine (==5.0.0)"]
+
[[package]]
name = "python-jose"
version = "3.3.0"
@@ -7260,6 +7367,17 @@ cryptography = ["cryptography (>=3.4.0)"]
pycrypto = ["pyasn1", "pycrypto (>=2.6.0,<2.7.0)"]
pycryptodome = ["pyasn1", "pycryptodome (>=3.3.1,<4.0.0)"]
+[[package]]
+name = "python-magic"
+version = "0.4.27"
+description = "File type identification using libmagic"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
+files = [
+ {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"},
+ {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"},
+]
+
[[package]]
name = "python-multipart"
version = "0.0.7"
@@ -7274,6 +7392,22 @@ files = [
[package.extras]
dev = ["atomicwrites (==1.2.1)", "attrs (==19.2.0)", "coverage (==6.5.0)", "hatch", "invoke (==2.2.0)", "more-itertools (==4.3.0)", "pbr (==4.3.0)", "pluggy (==1.0.0)", "py (==1.11.0)", "pytest (==7.2.0)", "pytest-cov (==4.0.0)", "pytest-timeout (==2.1.0)", "pyyaml (==5.1)"]
+[[package]]
+name = "python-pptx"
+version = "0.6.23"
+description = "Generate and manipulate Open XML PowerPoint (.pptx) files"
+optional = false
+python-versions = "*"
+files = [
+ {file = "python-pptx-0.6.23.tar.gz", hash = "sha256:587497ff28e779ab18dbb074f6d4052893c85dedc95ed75df319364f331fedee"},
+ {file = "python_pptx-0.6.23-py3-none-any.whl", hash = "sha256:dd0527194627a2b7cc05f3ba23ecaa2d9a0d5ac9b6193a28ed1b7a716f4217d4"},
+]
+
+[package.dependencies]
+lxml = ">=3.1.0"
+Pillow = ">=3.3.2"
+XlsxWriter = ">=0.5.7"
+
[[package]]
name = "python-socketio"
version = "5.11.2"
@@ -7364,7 +7498,6 @@ files = [
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
@@ -7561,6 +7694,111 @@ all = ["emoji", "langchain (>=0.0.321)", "ltp", "sentencepiece", "torch", "torch
data-clean = ["emoji", "ltp", "sentencepiece", "torch", "torch (<=1.13.1)"]
langchain = ["langchain (>=0.0.321)"]
+[[package]]
+name = "rapidfuzz"
+version = "3.9.3"
+description = "rapid fuzzy string matching"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bdb8c5b8e29238ec80727c2ba3b301efd45aa30c6a7001123a6647b8e6f77ea4"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b3bd0d9632088c63a241f217742b1cf86e2e8ae573e01354775bd5016d12138c"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:153f23c03d4917f6a1fc2fb56d279cc6537d1929237ff08ee7429d0e40464a18"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96c5225e840f1587f1bac8fa6f67562b38e095341576e82b728a82021f26d62"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b777cd910ceecd738adc58593d6ed42e73f60ad04ecdb4a841ae410b51c92e0e"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:53e06e4b81f552da04940aa41fc556ba39dee5513d1861144300c36c33265b76"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c7ca5b6050f18fdcacdada2dc5fb7619ff998cd9aba82aed2414eee74ebe6cd"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:87bb8d84cb41446a808c4b5f746e29d8a53499381ed72f6c4e456fe0f81c80a8"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:959a15186d18425d19811bea86a8ffbe19fd48644004d29008e636631420a9b7"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a24603dd05fb4e3c09d636b881ce347e5f55f925a6b1b4115527308a323b9f8e"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0d055da0e801c71dd74ba81d72d41b2fa32afa182b9fea6b4b199d2ce937450d"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:875b581afb29a7213cf9d98cb0f98df862f1020bce9d9b2e6199b60e78a41d14"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-win32.whl", hash = "sha256:6073a46f61479a89802e3f04655267caa6c14eb8ac9d81a635a13805f735ebc1"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:119c010e20e561249b99ca2627f769fdc8305b07193f63dbc07bca0a6c27e892"},
+ {file = "rapidfuzz-3.9.3-cp310-cp310-win_arm64.whl", hash = "sha256:790b0b244f3213581d42baa2fed8875f9ee2b2f9b91f94f100ec80d15b140ba9"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f57e8305c281e8c8bc720515540e0580355100c0a7a541105c6cafc5de71daae"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a4fc7b784cf987dbddc300cef70e09a92ed1bce136f7bb723ea79d7e297fe76d"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b422c0a6fe139d5447a0766268e68e6a2a8c2611519f894b1f31f0a392b9167"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f50fed4a9b0c9825ff37cf0bccafd51ff5792090618f7846a7650f21f85579c9"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b80eb7cbe62348c61d3e67e17057cddfd6defab168863028146e07d5a8b24a89"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f45be77ec82da32ce5709a362e236ccf801615cc7163b136d1778cf9e31b14"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd84b7f652a5610733400307dc732f57c4a907080bef9520412e6d9b55bc9adc"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e6d27dad8c990218b8cd4a5c99cbc8834f82bb46ab965a7265d5aa69fc7ced7"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:05ee0696ebf0dfe8f7c17f364d70617616afc7dafe366532730ca34056065b8a"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:2bc8391749e5022cd9e514ede5316f86e332ffd3cfceeabdc0b17b7e45198a8c"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:93981895602cf5944d89d317ae3b1b4cc684d175a8ae2a80ce5b65615e72ddd0"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:754b719a4990735f66653c9e9261dcf52fd4d925597e43d6b9069afcae700d21"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-win32.whl", hash = "sha256:14c9f268ade4c88cf77ab007ad0fdf63699af071ee69378de89fff7aa3cae134"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc1991b4cde6c9d3c0bbcb83d5581dc7621bec8c666c095c65b4277233265a82"},
+ {file = "rapidfuzz-3.9.3-cp311-cp311-win_arm64.whl", hash = "sha256:0c34139df09a61b1b557ab65782ada971b4a3bce7081d1b2bee45b0a52231adb"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d6a210347d6e71234af5c76d55eeb0348b026c9bb98fe7c1cca89bac50fb734"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b300708c917ce52f6075bdc6e05b07c51a085733650f14b732c087dc26e0aaad"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83ea7ca577d76778250421de61fb55a719e45b841deb769351fc2b1740763050"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8319838fb5b7b5f088d12187d91d152b9386ce3979ed7660daa0ed1bff953791"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:505d99131afd21529293a9a7b91dfc661b7e889680b95534756134dc1cc2cd86"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c52970f7784518d7c82b07a62a26e345d2de8c2bd8ed4774e13342e4b3ff4200"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:143caf7247449055ecc3c1e874b69e42f403dfc049fc2f3d5f70e1daf21c1318"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b8ab0fa653d9225195a8ff924f992f4249c1e6fa0aea563f685e71b81b9fcccf"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57e7c5bf7b61c7320cfa5dde1e60e678d954ede9bb7da8e763959b2138391401"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51fa1ba84653ab480a2e2044e2277bd7f0123d6693051729755addc0d015c44f"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:17ff7f7eecdb169f9236e3b872c96dbbaf116f7787f4d490abd34b0116e3e9c8"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:afe7c72d3f917b066257f7ff48562e5d462d865a25fbcabf40fca303a9fa8d35"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-win32.whl", hash = "sha256:e53ed2e9b32674ce96eed80b3b572db9fd87aae6742941fb8e4705e541d861ce"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:35b7286f177e4d8ba1e48b03612f928a3c4bdac78e5651379cec59f95d8651e6"},
+ {file = "rapidfuzz-3.9.3-cp312-cp312-win_arm64.whl", hash = "sha256:e6e4b9380ed4758d0cb578b0d1970c3f32dd9e87119378729a5340cb3169f879"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a39890013f6d5b056cc4bfdedc093e322462ece1027a57ef0c636537bdde7531"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b5bc0fdbf419493163c5c9cb147c5fbe95b8e25844a74a8807dcb1a125e630cf"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:efe6e200a75a792d37b960457904c4fce7c928a96ae9e5d21d2bd382fe39066e"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de077c468c225d4c18f7188c47d955a16d65f21aab121cbdd98e3e2011002c37"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f917eaadf5388466a95f6a236f678a1588d231e52eda85374077101842e794e"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:858ba57c05afd720db8088a8707079e8d024afe4644001fe0dbd26ef7ca74a65"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d36447d21b05f90282a6f98c5a33771805f9222e5d0441d03eb8824e33e5bbb4"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:acbe4b6f1ccd5b90c29d428e849aa4242e51bb6cab0448d5f3c022eb9a25f7b1"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:53c7f27cdf899e94712972237bda48cfd427646aa6f5d939bf45d084780e4c16"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:6175682a829c6dea4d35ed707f1dadc16513270ef64436568d03b81ccb6bdb74"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:5276df395bd8497397197fca2b5c85f052d2e6a66ffc3eb0544dd9664d661f95"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:77b5c4f3e72924d7845f0e189c304270066d0f49635cf8a3938e122c437e58de"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-win32.whl", hash = "sha256:8add34061e5cd561c72ed4febb5c15969e7b25bda2bb5102d02afc3abc1f52d0"},
+ {file = "rapidfuzz-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:604e0502a39cf8e67fa9ad239394dddad4cdef6d7008fdb037553817d420e108"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21047f55d674614eb4b0ab34e35c3dc66f36403b9fbfae645199c4a19d4ed447"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a56da3aff97cb56fe85d9ca957d1f55dbac7c27da927a86a2a86d8a7e17f80aa"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:964c08481aec2fe574f0062e342924db2c6b321391aeb73d68853ed42420fd6d"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e2b827258beefbe5d3f958243caa5a44cf46187eff0c20e0b2ab62d1550327a"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6e65a301fcd19fbfbee3a514cc0014ff3f3b254b9fd65886e8a9d6957fb7bca"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cbe93ba1725a8d47d2b9dca6c1f435174859427fbc054d83de52aea5adc65729"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca21c0a34adee582775da997a600283e012a608a107398d80a42f9a57ad323d"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:256e07d3465173b2a91c35715a2277b1ee3ae0b9bbab4e519df6af78570741d0"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:802ca2cc8aa6b8b34c6fdafb9e32540c1ba05fca7ad60b3bbd7ec89ed1797a87"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:dd789100fc852cffac1449f82af0da139d36d84fd9faa4f79fc4140a88778343"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:5d0abbacdb06e27ff803d7ae0bd0624020096802758068ebdcab9bd49cf53115"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:378d1744828e27490a823fc6fe6ebfb98c15228d54826bf4e49e4b76eb5f5579"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-win32.whl", hash = "sha256:5d0cb272d43e6d3c0dedefdcd9d00007471f77b52d2787a4695e9dd319bb39d2"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:15e4158ac4b3fb58108072ec35b8a69165f651ba1c8f43559a36d518dbf9fb3f"},
+ {file = "rapidfuzz-3.9.3-cp39-cp39-win_arm64.whl", hash = "sha256:58c6a4936190c558d5626b79fc9e16497e5df7098589a7e80d8bff68148ff096"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5410dc848c947a603792f4f51b904a3331cf1dc60621586bfbe7a6de72da1091"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:282d55700a1a3d3a7980746eb2fcd48c9bbc1572ebe0840d0340d548a54d01fe"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc1037507810833646481f5729901a154523f98cbebb1157ba3a821012e16402"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e33f779391caedcba2ba3089fb6e8e557feab540e9149a5c3f7fea7a3a7df37"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41a81a9f311dc83d22661f9b1a1de983b201322df0c4554042ffffd0f2040c37"},
+ {file = "rapidfuzz-3.9.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:a93250bd8fae996350c251e1752f2c03335bb8a0a5b0c7e910a593849121a435"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3617d1aa7716c57d120b6adc8f7c989f2d65bc2b0cbd5f9288f1fc7bf469da11"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:ad04a3f5384b82933213bba2459f6424decc2823df40098920856bdee5fd6e88"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8709918da8a88ad73c9d4dd0ecf24179a4f0ceba0bee21efc6ea21a8b5290349"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b770f85eab24034e6ef7df04b2bfd9a45048e24f8a808e903441aa5abde8ecdd"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:930b4e6fdb4d914390141a2b99a6f77a52beacf1d06aa4e170cba3a98e24c1bc"},
+ {file = "rapidfuzz-3.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:c8444e921bfc3757c475c4f4d7416a7aa69b2d992d5114fe55af21411187ab0d"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2c1d3ef3878f871abe6826e386c3d61b5292ef5f7946fe646f4206b85836b5da"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d861bf326ee7dabc35c532a40384541578cd1ec1e1b7db9f9ecbba56eb76ca22"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cde6b9d9ba5007077ee321ec722fa714ebc0cbd9a32ccf0f4dd3cc3f20952d71"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bb6546e7b6bed1aefbe24f68a5fb9b891cc5aef61bca6c1a7b1054b7f0359bb"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d8a57261ef7996d5ced7c8cba9189ada3fbeffd1815f70f635e4558d93766cb"},
+ {file = "rapidfuzz-3.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:67201c02efc596923ad950519e0b75ceb78d524177ea557134d6567b9ac2c283"},
+ {file = "rapidfuzz-3.9.3.tar.gz", hash = "sha256:b398ea66e8ed50451bce5997c430197d5e4b06ac4aa74602717f792d8d8d06e2"},
+]
+
+[package.extras]
+full = ["numpy"]
+
[[package]]
name = "realtime"
version = "1.0.5"
@@ -7722,6 +7960,20 @@ requests = ">=2.0.0"
[package.extras]
rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
+[[package]]
+name = "requests-toolbelt"
+version = "1.0.0"
+description = "A utility belt for advanced users of python-requests"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
+files = [
+ {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"},
+ {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"},
+]
+
+[package.dependencies]
+requests = ">=2.0.1,<3.0.0"
+
[[package]]
name = "respx"
version = "0.21.1"
@@ -8411,6 +8663,20 @@ files = [
[package.dependencies]
mpmath = ">=1.1.0,<1.4.0"
+[[package]]
+name = "tabulate"
+version = "0.9.0"
+description = "Pretty-print tabular data"
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"},
+ {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"},
+]
+
+[package.extras]
+widechars = ["wcwidth"]
+
[[package]]
name = "tbb"
version = "2021.12.0"
@@ -9182,6 +9448,139 @@ files = [
pyperclip = "*"
six = "*"
+[[package]]
+name = "unstructured"
+version = "0.14.5"
+description = "A library that prepares raw documents for downstream ML tasks."
+optional = false
+python-versions = "<3.13,>=3.9.0"
+files = [
+ {file = "unstructured-0.14.5-py3-none-any.whl", hash = "sha256:2286180ac089b691e1effb73c2ab17b7809011fbf7f751439301b12a4c984131"},
+ {file = "unstructured-0.14.5.tar.gz", hash = "sha256:f37975273cdcf8f05768ef2f86abaf3d8f805992f6acb0441c2be00fa4ef6588"},
+]
+
+[package.dependencies]
+backoff = "*"
+beautifulsoup4 = "*"
+chardet = "*"
+dataclasses-json = "*"
+emoji = "*"
+filetype = "*"
+langdetect = "*"
+lxml = "*"
+markdown = {version = "*", optional = true, markers = "extra == \"md\""}
+nltk = "*"
+numpy = "*"
+python-docx = {version = ">=1.1.2", optional = true, markers = "extra == \"docx\""}
+python-iso639 = "*"
+python-magic = "*"
+python-pptx = {version = "<=0.6.23", optional = true, markers = "extra == \"pptx\""}
+rapidfuzz = "*"
+requests = "*"
+tabulate = "*"
+typing-extensions = "*"
+unstructured-client = "*"
+wrapt = "*"
+
+[package.extras]
+airtable = ["pyairtable"]
+all-docs = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.33)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
+astra = ["astrapy"]
+azure = ["adlfs", "fsspec"]
+azure-cognitive-search = ["azure-search-documents"]
+bedrock = ["boto3", "langchain-community"]
+biomed = ["bs4"]
+box = ["boxfs", "fsspec"]
+chroma = ["chromadb", "importlib-metadata (>=7.1.0)", "typer (<=0.9.0)"]
+clarifai = ["clarifai"]
+confluence = ["atlassian-python-api"]
+csv = ["pandas"]
+databricks-volumes = ["databricks-sdk"]
+delta-table = ["deltalake", "fsspec"]
+discord = ["discord-py"]
+doc = ["python-docx (>=1.1.2)"]
+docx = ["python-docx (>=1.1.2)"]
+dropbox = ["dropboxdrivefs", "fsspec"]
+elasticsearch = ["elasticsearch"]
+embed-huggingface = ["huggingface", "langchain-community", "sentence-transformers"]
+embed-octoai = ["openai", "tiktoken"]
+embed-vertexai = ["langchain", "langchain-community", "langchain-google-vertexai"]
+embed-voyageai = ["langchain", "langchain-voyageai"]
+epub = ["pypandoc"]
+gcs = ["bs4", "fsspec", "gcsfs"]
+github = ["pygithub (>1.58.0)"]
+gitlab = ["python-gitlab"]
+google-drive = ["google-api-python-client"]
+hubspot = ["hubspot-api-client", "urllib3"]
+huggingface = ["langdetect", "sacremoses", "sentencepiece", "torch", "transformers"]
+image = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.33)", "unstructured.pytesseract (>=0.3.12)"]
+jira = ["atlassian-python-api"]
+local-inference = ["effdet", "google-cloud-vision", "markdown", "networkx", "onnx", "openpyxl", "pandas", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypandoc", "pypdf", "pytesseract", "python-docx (>=1.1.2)", "python-oxmsg", "python-pptx (<=0.6.23)", "unstructured-inference (==0.7.33)", "unstructured.pytesseract (>=0.3.12)", "xlrd"]
+md = ["markdown"]
+mongodb = ["pymongo"]
+msg = ["python-oxmsg"]
+notion = ["htmlBuilder", "notion-client"]
+odt = ["pypandoc", "python-docx (>=1.1.2)"]
+onedrive = ["Office365-REST-Python-Client", "bs4", "msal"]
+openai = ["langchain-community", "openai", "tiktoken"]
+opensearch = ["opensearch-py"]
+org = ["pypandoc"]
+outlook = ["Office365-REST-Python-Client", "msal"]
+paddleocr = ["unstructured.paddleocr (==2.6.1.3)"]
+pdf = ["effdet", "google-cloud-vision", "onnx", "pdf2image", "pdfminer.six", "pikepdf", "pillow-heif", "pypdf", "pytesseract", "unstructured-inference (==0.7.33)", "unstructured.pytesseract (>=0.3.12)"]
+pinecone = ["pinecone-client (>=3.7.1)"]
+postgres = ["psycopg2-binary"]
+ppt = ["python-pptx (<=0.6.23)"]
+pptx = ["python-pptx (<=0.6.23)"]
+qdrant = ["qdrant-client"]
+reddit = ["praw"]
+rst = ["pypandoc"]
+rtf = ["pypandoc"]
+s3 = ["fsspec", "s3fs"]
+salesforce = ["simple-salesforce"]
+sftp = ["fsspec", "paramiko"]
+sharepoint = ["Office365-REST-Python-Client", "msal"]
+slack = ["slack-sdk"]
+tsv = ["pandas"]
+weaviate = ["weaviate-client"]
+wikipedia = ["wikipedia"]
+xlsx = ["networkx", "openpyxl", "pandas", "xlrd"]
+
+[[package]]
+name = "unstructured-client"
+version = "0.23.2"
+description = "Python Client SDK for Unstructured API"
+optional = false
+python-versions = ">=3.8"
+files = [
+ {file = "unstructured-client-0.23.2.tar.gz", hash = "sha256:26864737a6c27471cba8bcb714e4e31038f62f84552b3ead5f241bc56fa42288"},
+ {file = "unstructured_client-0.23.2-py3-none-any.whl", hash = "sha256:b3be91e7c2498aa9108a43dde4cbb75e450a87fabb450f0687c1900da7da73f6"},
+]
+
+[package.dependencies]
+certifi = ">=2023.7.22"
+charset-normalizer = ">=3.2.0"
+dataclasses-json = ">=0.6.4"
+deepdiff = ">=6.0"
+httpx = ">=0.27.0"
+idna = ">=3.4"
+jsonpath-python = ">=1.0.6"
+marshmallow = ">=3.19.0"
+mypy-extensions = ">=1.0.0"
+nest-asyncio = ">=1.6.0"
+packaging = ">=23.1"
+pypdf = ">=4.0"
+python-dateutil = ">=2.8.2"
+requests = ">=2.31.0"
+requests-toolbelt = ">=1.0.0"
+six = ">=1.16.0"
+typing-extensions = ">=4.7.1"
+typing-inspect = ">=0.9.0"
+urllib3 = ">=1.26.18"
+
+[package.extras]
+dev = ["pylint (==3.1.0)"]
+
[[package]]
name = "upstash-vector"
version = "0.4.0"
@@ -9715,6 +10114,17 @@ files = [
[package.dependencies]
h11 = ">=0.9.0,<1"
+[[package]]
+name = "xlsxwriter"
+version = "3.2.0"
+description = "A Python module for creating Excel XLSX files."
+optional = false
+python-versions = ">=3.6"
+files = [
+ {file = "XlsxWriter-3.2.0-py3-none-any.whl", hash = "sha256:ecfd5405b3e0e228219bcaf24c2ca0915e012ca9464a14048021d21a995d490e"},
+ {file = "XlsxWriter-3.2.0.tar.gz", hash = "sha256:9977d0c661a72866a61f9f7a809e25ebbb0fb7036baa3b9fe74afcfca6b3cb8c"},
+]
+
[[package]]
name = "xxhash"
version = "3.4.1"
@@ -10051,6 +10461,7 @@ test = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
[extras]
+cassio = ["cassio"]
couchbase = ["couchbase"]
deploy = ["celery", "flower", "redis"]
local = ["ctransformers", "llama-cpp-python", "sentence-transformers"]
@@ -10058,4 +10469,4 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.13"
-content-hash = "0ee3f3bef82d57be2ab4ae7b70215ebca67b5bd5223e6a9322ee1837516a3cc6"
+content-hash = "1bb2c31cf0c53a2931a5aa72db3aa06036bc54610f938a733d697e770079957d"
diff --git a/pyproject.toml b/pyproject.toml
index cf11dc07d..c65d8528e 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -86,6 +86,8 @@ youtube-transcript-api = "^0.6.2"
markdown = "^3.6"
langchain-chroma = "^0.1.1"
upstash-vector = "^0.4.0"
+cassio = { extras = ["cassio"], version = "^0.1.7", optional = true }
+unstructured = {extras = ["docx", "md", "pptx"], version = "^0.14.4"}
[tool.poetry.group.dev.dependencies]
@@ -120,6 +122,7 @@ dictdiffer = "^0.9.0"
[tool.poetry.extras]
deploy = ["celery", "redis", "flower"]
couchbase = ["couchbase"]
+cassio = ["cassio"]
local = ["llama-cpp-python", "sentence-transformers", "ctransformers"]
diff --git a/src/backend/base/langflow/base/tools/base.py b/src/backend/base/langflow/base/tools/base.py
index e1c4d5fdc..c9422e268 100644
--- a/src/backend/base/langflow/base/tools/base.py
+++ b/src/backend/base/langflow/base/tools/base.py
@@ -9,7 +9,7 @@ def build_status_from_tool(tool: Tool):
tool (Tool): The tool object to build the status for.
Returns:
- str: The status string representation of the tool, including its name, description, and arguments (if any).
+ str: The status string representation of the tool, including its name, description, arguments (if any), and args_schema (if any).
"""
description_repr = repr(tool.description).strip("'")
args_str = "\n".join(
@@ -19,5 +19,8 @@ def build_status_from_tool(tool: Tool):
if "description" in arg_data
]
)
+ # Include args_schema information
+ args_schema_str = repr(tool.args_schema) if tool.args_schema else "None"
status = f"Name: {tool.name}\nDescription: {description_repr}"
+ status += f"\nArgs Schema: {args_schema_str}"
return status + (f"\nArguments:\n{args_str}" if args_str else "")
diff --git a/src/backend/base/langflow/components/memories/AstraDBMessageReader.py b/src/backend/base/langflow/components/memories/AstraDBMessageReader.py
index f2e93d19d..c61909887 100644
--- a/src/backend/base/langflow/components/memories/AstraDBMessageReader.py
+++ b/src/backend/base/langflow/components/memories/AstraDBMessageReader.py
@@ -1,10 +1,8 @@
from typing import Optional, cast
-from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
from langflow.base.memory.memory import BaseMemoryComponent
-from langflow.field_typing import Text
-from langflow.schema import Record
+from langflow.schema.schema import Record
class AstraDBMessageReaderComponent(BaseMemoryComponent):
@@ -51,6 +49,14 @@ class AstraDBMessageReaderComponent(BaseMemoryComponent):
Returns:
list[Record]: A list of Record objects representing the search results.
"""
+ try:
+ from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
+ except ImportError:
+ raise ImportError(
+ "Could not import langchain Astra DB integration package. "
+ "Please install it with `pip install langchain-astradb`."
+ )
+
memory: AstraDBChatMessageHistory = cast(AstraDBChatMessageHistory, kwargs.get("memory"))
if not memory:
raise ValueError("AstraDBChatMessageHistory instance is required.")
@@ -63,14 +69,14 @@ class AstraDBMessageReaderComponent(BaseMemoryComponent):
def build(
self,
- session_id: Text,
+ session_id: str,
collection_name: str,
token: str,
api_endpoint: str,
namespace: Optional[str] = None,
) -> list[Record]:
try:
- pass
+ from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
except ImportError:
raise ImportError(
"Could not import langchain Astra DB integration package. "
diff --git a/src/backend/base/langflow/components/memories/AstraDBMessageWriter.py b/src/backend/base/langflow/components/memories/AstraDBMessageWriter.py
index a95c7a15c..c63f27db8 100644
--- a/src/backend/base/langflow/components/memories/AstraDBMessageWriter.py
+++ b/src/backend/base/langflow/components/memories/AstraDBMessageWriter.py
@@ -4,8 +4,9 @@ from langchain_astradb import AstraDBChatMessageHistory
from langchain_core.messages import BaseMessage
from langflow.base.memory.memory import BaseMemoryComponent
-from langflow.field_typing import Text
-from langflow.schema import Record
+from langflow.schema.schema import Record
+
+from langchain_core.messages import BaseMessage
class AstraDBMessageWriterComponent(BaseMemoryComponent):
@@ -50,7 +51,7 @@ class AstraDBMessageWriterComponent(BaseMemoryComponent):
self,
sender: str,
sender_name: str,
- text: Text,
+ text: str,
session_id: str,
metadata: Optional[dict] = None,
**kwargs,
@@ -59,17 +60,27 @@ class AstraDBMessageWriterComponent(BaseMemoryComponent):
Adds a message to the AstraDBChatMessageHistory memory.
Args:
- sender (Text): The type of the message sender. Valid values are "Machine" or "User".
- sender_name (Text): The name of the message sender.
- text (Text): The content of the message.
- session_id (Text): The session ID associated with the message.
+ sender (str): The type of the message sender. Typically "ai" or "human".
+ sender_name (str): The name of the message sender.
+ text (str): The content of the message.
+ session_id (str): The session ID associated with the message.
metadata (dict | None, optional): Additional metadata for the message. Defaults to None.
- **kwargs: Additional keyword arguments.
+ **kwargs: Additional keyword arguments, including:
+ memory (AstraDBChatMessageHistory | None): The memory instance to add the message to.
+
Raises:
ValueError: If the AstraDBChatMessageHistory instance is not provided.
"""
+ try:
+ from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
+ except ImportError:
+ raise ImportError(
+ "Could not import langchain Astra DB integration package. "
+ "Please install it with `pip install langchain-astradb`."
+ )
+
memory: AstraDBChatMessageHistory | None = kwargs.pop("memory", None)
if memory is None:
raise ValueError("AstraDBChatMessageHistory instance is required.")
@@ -89,14 +100,14 @@ class AstraDBMessageWriterComponent(BaseMemoryComponent):
def build(
self,
input_value: Record,
- session_id: Text,
+ session_id: str,
collection_name: str,
token: str,
api_endpoint: str,
namespace: Optional[str] = None,
) -> Record:
try:
- pass
+ from langchain_astradb.chat_message_histories import AstraDBChatMessageHistory
except ImportError:
raise ImportError(
"Could not import langchain Astra DB integration package. "
diff --git a/src/backend/base/langflow/components/memories/CassandraMessageReader.py b/src/backend/base/langflow/components/memories/CassandraMessageReader.py
new file mode 100644
index 000000000..3545d444a
--- /dev/null
+++ b/src/backend/base/langflow/components/memories/CassandraMessageReader.py
@@ -0,0 +1,86 @@
+from typing import Optional, cast
+
+from langchain_community.chat_message_histories import CassandraChatMessageHistory
+
+from langflow.base.memory.memory import BaseMemoryComponent
+from langflow.schema.schema import Record
+
+
+class CassandraMessageReaderComponent(BaseMemoryComponent):
+ display_name = "Cassandra Message Reader"
+ description = "Retrieves stored chat messages from a Cassandra table on Astra DB."
+
+ def build_config(self):
+ return {
+ "session_id": {
+ "display_name": "Session ID",
+ "info": "Session ID of the chat history.",
+ "input_types": ["Text"],
+ },
+ "database_id": {
+ "display_name": "Database ID",
+ "info": "The Astra database ID.",
+ },
+ "table_name": {
+ "display_name": "Table Name",
+ "info": "The name of the table where messages are stored.",
+ },
+ "token": {
+ "display_name": "Token",
+ "info": "Authentication token for accessing Cassandra on Astra DB.",
+ "password": True,
+ },
+ "keyspace": {
+ "display_name": "Keyspace",
+ "info": "Optional key space within Astra DB. The keyspace should already be created.",
+ "input_types": ["Text"],
+ "advanced": True,
+ },
+ }
+
+ def get_messages(self, **kwargs) -> list[Record]:
+ """
+ Retrieves messages from the CassandraChatMessageHistory memory.
+
+ Args:
+ memory (CassandraChatMessageHistory): The CassandraChatMessageHistory instance to retrieve messages from.
+
+ Returns:
+ list[Record]: A list of Record objects representing the search results.
+ """
+ memory: CassandraChatMessageHistory = cast(CassandraChatMessageHistory, kwargs.get("memory"))
+ if not memory:
+ raise ValueError("CassandraChatMessageHistory instance is required.")
+
+ # Get messages from the memory
+ messages = memory.messages
+ results = [Record.from_lc_message(message) for message in messages]
+
+ return list(results)
+
+ def build(
+ self,
+ session_id: str,
+ table_name: str,
+ token: str,
+ database_id: str,
+ keyspace: Optional[str] = None,
+ ) -> list[Record]:
+ try:
+ import cassio
+ except ImportError:
+ raise ImportError(
+ "Could not import cassio integration package. " "Please install it with `pip install cassio`."
+ )
+
+ cassio.init(token=token, database_id=database_id)
+ memory = CassandraChatMessageHistory(
+ session_id=session_id,
+ table_name=table_name,
+ keyspace=keyspace,
+ )
+
+ records = self.get_messages(memory=memory)
+ self.status = records
+
+ return records
diff --git a/src/backend/base/langflow/components/memories/CassandraMessageWriter.py b/src/backend/base/langflow/components/memories/CassandraMessageWriter.py
new file mode 100644
index 000000000..716364b64
--- /dev/null
+++ b/src/backend/base/langflow/components/memories/CassandraMessageWriter.py
@@ -0,0 +1,122 @@
+from typing import Optional
+
+from langflow.base.memory.memory import BaseMemoryComponent
+from langflow.schema.schema import Record
+
+from langchain_core.messages import BaseMessage
+from langchain_community.chat_message_histories import CassandraChatMessageHistory
+
+
+class CassandraMessageWriterComponent(BaseMemoryComponent):
+ display_name = "Cassandra Message Writer"
+ description = "Writes a message to a Cassandra table on Astra DB."
+
+ def build_config(self):
+ return {
+ "input_value": {
+ "display_name": "Input Record",
+ "info": "Record to write to Cassandra.",
+ },
+ "session_id": {
+ "display_name": "Session ID",
+ "info": "Session ID of the chat history.",
+ "input_types": ["Text"],
+ },
+ "database_id": {
+ "display_name": "Database ID",
+ "info": "The Astra database ID.",
+ },
+ "table_name": {
+ "display_name": "Table Name",
+ "info": "The name of the table where messages will be stored.",
+ },
+ "token": {
+ "display_name": "Token",
+ "info": "Authentication token for accessing Cassandra on Astra DB.",
+ "password": True,
+ },
+ "keyspace": {
+ "display_name": "Keyspace",
+ "info": "Optional key space within Astra DB. The keyspace should already be created.",
+ "input_types": ["Text"],
+ "advanced": True,
+ },
+ "ttl_seconds": {
+ "display_name": "TTL Seconds",
+ "info": "Optional time-to-live for the messages.",
+ "input_types": ["Number"],
+ "advanced": True,
+ },
+ }
+
+ def add_message(
+ self,
+ sender: str,
+ sender_name: str,
+ text: str,
+ session_id: str,
+ metadata: Optional[dict] = None,
+ **kwargs,
+ ):
+ """
+ Adds a message to the CassandraChatMessageHistory memory.
+
+ Args:
+ sender (str): The type of the message sender. Typically "ai" or "human".
+ sender_name (str): The name of the message sender.
+ text (str): The content of the message.
+ session_id (str): The session ID associated with the message.
+ metadata (dict | None, optional): Additional metadata for the message. Defaults to None.
+ **kwargs: Additional keyword arguments, including:
+ memory (CassandraChatMessageHistory | None): The memory instance to add the message to.
+
+
+ Raises:
+ ValueError: If the CassandraChatMessageHistory instance is not provided.
+
+ """
+ memory: CassandraChatMessageHistory | None = kwargs.pop("memory", None)
+ if memory is None:
+ raise ValueError("CassandraChatMessageHistory instance is required.")
+
+ text_list = [
+ BaseMessage(
+ content=text,
+ sender=sender,
+ sender_name=sender_name,
+ metadata=metadata,
+ session_id=session_id,
+ )
+ ]
+
+ memory.add_messages(text_list)
+
+ def build(
+ self,
+ input_value: Record,
+ session_id: str,
+ table_name: str,
+ token: str,
+ database_id: str,
+ keyspace: Optional[str] = None,
+ ttl_seconds: Optional[int] = None,
+ ) -> Record:
+ try:
+ import cassio
+ except ImportError:
+ raise ImportError(
+ "Could not import cassio integration package. " "Please install it with `pip install cassio`."
+ )
+
+ cassio.init(token=token, database_id=database_id)
+ memory = CassandraChatMessageHistory(
+ session_id=session_id,
+ table_name=table_name,
+ keyspace=keyspace,
+ ttl_seconds=ttl_seconds,
+ )
+
+ self.add_message(**input_value.data, memory=memory)
+ self.status = f"Added message to Cassandra memory for session {session_id}"
+
+ return input_value
diff --git a/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py b/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py
index ff26d5923..7358762bc 100644
--- a/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py
+++ b/src/backend/base/langflow/components/model_specs/ChatOpenAISpecs.py
@@ -28,7 +28,7 @@ class ChatOpenAIComponent(CustomComponent):
"model_name": {"display_name": "Model Name", "advanced": False, "options": MODEL_NAMES},
"openai_api_base": {
"display_name": "OpenAI API Base",
- "advanced": False,
+ "advanced": True,
"required": False,
"info": (
"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\n"
diff --git a/src/backend/base/langflow/components/vectorsearch/CassandraSearch.py b/src/backend/base/langflow/components/vectorsearch/CassandraSearch.py
new file mode 100644
index 000000000..8ee558276
--- /dev/null
+++ b/src/backend/base/langflow/components/vectorsearch/CassandraSearch.py
@@ -0,0 +1,94 @@
+from typing import Any, List, Optional, Tuple
+
+from langflow.components.vectorstores.Cassandra import CassandraVectorStoreComponent
+from langflow.components.vectorstores.base.model import LCVectorStoreComponent
+from langflow.field_typing import Embeddings, Text
+from langflow.schema import Record
+from langchain_community.utilities.cassandra import SetupMode
+
+
+class CassandraSearchComponent(LCVectorStoreComponent):
+ display_name = "Cassandra Search"
+ description = "Searches an existing Cassandra Vector Store."
+ icon = "Cassandra"
+ field_order = ["token", "database_id", "table_name", "input_value", "embedding"]
+
+ def build_config(self):
+ return {
+ "search_type": {
+ "display_name": "Search Type",
+ "options": ["Similarity", "MMR"],
+ },
+ "input_value": {
+ "display_name": "Input Value",
+ "info": "Input value to search",
+ },
+ "embedding": {"display_name": "Embedding", "info": "Embedding to use"},
+ "token": {
+ "display_name": "Token",
+ "info": "Authentication token for accessing Cassandra on Astra DB.",
+ "password": True,
+ },
+ "database_id": {
+ "display_name": "Database ID",
+ "info": "The Astra database ID.",
+ },
+ "table_name": {
+ "display_name": "Table Name",
+ "info": "The name of the table where vectors will be stored.",
+ },
+ "keyspace": {
+ "display_name": "Keyspace",
+ "info": "Optional key space within Astra DB. The keyspace should already be created.",
+ "advanced": True,
+ },
+ "body_index_options": {
+ "display_name": "Body Index Options",
+ "info": "Optional options used to create the body index.",
+ "advanced": True,
+ },
+ "setup_mode": {
+ "display_name": "Setup Mode",
+ "info": "Configuration mode for setting up the Cassandra table, with options like 'Sync', 'Async', or 'Off'.",
+ "options": ["Sync", "Async", "Off"],
+ "advanced": True,
+ },
+ "number_of_results": {
+ "display_name": "Number of Results",
+ "info": "Number of results to return.",
+ "advanced": True,
+ },
+ }
+
+ def build(
+ self,
+ embedding: Embeddings,
+ table_name: str,
+ input_value: Text,
+ token: str,
+ database_id: str,
+ search_type: str = "similarity",
+ number_of_results: int = 4,
+ keyspace: Optional[str] = None,
+ body_index_options: Optional[List[Tuple[str, Any]]] = None,
+ setup_mode: SetupMode = SetupMode.SYNC,
+ ) -> List[Record]:
+ vector_store = CassandraVectorStoreComponent().build(
+ embedding=embedding,
+ table_name=table_name,
+ token=token,
+ database_id=database_id,
+ keyspace=keyspace,
+ body_index_options=body_index_options,
+ setup_mode=setup_mode,
+ )
+
+ try:
+ return self.search_with_vector_store(input_value, search_type, vector_store, k=number_of_results)
+ except KeyError as e:
+ if "content" in str(e):
+ raise ValueError(
+ "You should ingest data through Langflow (or LangChain) to query it in Langflow. Your collection does not contain a field name 'content'."
+ )
+ else:
+ raise e
diff --git a/src/backend/base/langflow/components/vectorstores/AstraDB.py b/src/backend/base/langflow/components/vectorstores/AstraDB.py
index c9f7da8ee..cd4a06aea 100644
--- a/src/backend/base/langflow/components/vectorstores/AstraDB.py
+++ b/src/backend/base/langflow/components/vectorstores/AstraDB.py
@@ -1,12 +1,9 @@
from typing import List, Optional, Union
-from langchain_astradb import AstraDBVectorStore
-from langchain_astradb.utils.astradb import SetupMode
-from langchain_core.retrievers import BaseRetriever
-
from langflow.custom import CustomComponent
from langflow.field_typing import Embeddings, VectorStore
from langflow.schema import Record
+from langchain_core.retrievers import BaseRetriever
class AstraDBVectorStoreComponent(CustomComponent):
@@ -112,6 +109,15 @@ class AstraDBVectorStoreComponent(CustomComponent):
metadata_indexing_exclude: Optional[List[str]] = None,
collection_indexing_policy: Optional[dict] = None,
) -> Union[VectorStore, BaseRetriever]:
+ try:
+ from langchain_astradb import AstraDBVectorStore
+ from langchain_astradb.utils.astradb import SetupMode
+ except ImportError:
+ raise ImportError(
+ "Could not import langchain Astra DB integration package. "
+ "Please install it with `pip install langchain-astradb`."
+ )
+
try:
setup_mode_value = SetupMode[setup_mode.upper()]
except KeyError:
diff --git a/src/backend/base/langflow/components/vectorstores/Cassandra.py b/src/backend/base/langflow/components/vectorstores/Cassandra.py
new file mode 100644
index 000000000..34c21ccd0
--- /dev/null
+++ b/src/backend/base/langflow/components/vectorstores/Cassandra.py
@@ -0,0 +1,110 @@
+from typing import Any, List, Optional, Tuple
+from langchain_community.vectorstores import Cassandra
+from langchain_community.utilities.cassandra import SetupMode
+
+from langflow.custom import CustomComponent
+from langflow.field_typing import Embeddings, VectorStore
+from langflow.schema import Record
+
+
+class CassandraVectorStoreComponent(CustomComponent):
+ display_name = "Cassandra"
+ description = "Builds or loads a Cassandra Vector Store."
+ icon = "Cassandra"
+ field_order = ["token", "database_id", "table_name", "inputs", "embedding"]
+
+ def build_config(self):
+ return {
+ "inputs": {
+ "display_name": "Inputs",
+ "info": "Optional list of records to be processed and stored in the vector store.",
+ },
+ "embedding": {"display_name": "Embedding", "info": "Embedding to use"},
+ "token": {
+ "display_name": "Token",
+ "info": "Authentication token for accessing Cassandra on Astra DB.",
+ "password": True,
+ },
+ "database_id": {
+ "display_name": "Database ID",
+ "info": "The Astra database ID.",
+ },
+ "table_name": {
+ "display_name": "Table Name",
+ "info": "The name of the table where vectors will be stored.",
+ },
+ "keyspace": {
+ "display_name": "Keyspace",
+ "info": "Optional key space within Astra DB. The keyspace should already be created.",
+ "advanced": True,
+ },
+ "ttl_seconds": {
+ "display_name": "TTL Seconds",
+ "info": "Optional time-to-live for the added texts.",
+ "advanced": True,
+ },
+ "batch_size": {
+ "display_name": "Batch Size",
+ "info": "Optional number of records to process in a single batch.",
+ "advanced": True,
+ },
+ "body_index_options": {
+ "display_name": "Body Index Options",
+ "info": "Optional options used to create the body index.",
+ "advanced": True,
+ },
+ "setup_mode": {
+ "display_name": "Setup Mode",
+ "info": "Configuration mode for setting up the Cassandra table, with options like 'Sync', 'Async', or 'Off'.",
+ "options": ["Sync", "Async", "Off"],
+ "advanced": True,
+ },
+ }
+
+ def build(
+ self,
+ embedding: Embeddings,
+ token: str,
+ database_id: str,
+ inputs: Optional[List[Record]] = None,
+ keyspace: Optional[str] = None,
+ table_name: str = "",
+ ttl_seconds: Optional[int] = None,
+ batch_size: int = 16,
+ body_index_options: Optional[List[Tuple[str, Any]]] = None,
+ setup_mode: SetupMode = SetupMode.SYNC,
+ ) -> VectorStore:
+ try:
+ import cassio
+ except ImportError:
+ raise ImportError(
+ "Could not import cassio integration package. " "Please install it with `pip install cassio`."
+ )
+
+ cassio.init(
+ database_id=database_id,
+ token=token,
+ )
+
+ if inputs:
+ documents = [_input.to_lc_document() for _input in inputs]
+ table = Cassandra.from_documents(
+ documents=documents,
+ embedding=embedding,
+ table_name=table_name,
+ keyspace=keyspace,
+ ttl_seconds=ttl_seconds,
+ batch_size=batch_size,
+ body_index_options=body_index_options,
+ )
+ else:
+ table = Cassandra(
+ embedding=embedding,
+ table_name=table_name,
+ keyspace=keyspace,
+ ttl_seconds=ttl_seconds,
+ body_index_options=body_index_options,
+ setup_mode=setup_mode,
+ )
+
+ return table
diff --git a/src/backend/base/langflow/services/monitor/service.py b/src/backend/base/langflow/services/monitor/service.py
index 2badabc1f..8726ded20 100644
--- a/src/backend/base/langflow/services/monitor/service.py
+++ b/src/backend/base/langflow/services/monitor/service.py
@@ -1,6 +1,6 @@
from datetime import datetime
from pathlib import Path
-from typing import TYPE_CHECKING, Optional, Union
+from typing import TYPE_CHECKING, Optional, Union, List
import duckdb
from loguru import logger
@@ -107,12 +107,21 @@ class MonitorService(Service):
return self.exec_query(query)
- def delete_messages(self, message_ids: list[int]):
- query = f"DELETE FROM messages WHERE index IN ({','.join(map(str, message_ids))})"
+ def delete_messages(self, message_ids: Union[List[int], str]):
+ if isinstance(message_ids, list):
+ # If message_ids is a list, join the string representations of the integers
+ ids_str = ','.join(map(str, message_ids))
+ elif isinstance(message_ids, str):
+ # If message_ids is already a string, use it directly
+ ids_str = message_ids
+ else:
+ raise ValueError("message_ids must be a list of integers or a string")
+
+ query = f"DELETE FROM messages WHERE index IN ({ids_str})"
return self.exec_query(query)
- def update_message(self, message_id: int, **kwargs):
+ def update_message(self, message_id: str, **kwargs):
query = (
f"""UPDATE messages SET {', '.join(f"{k} = '{v}'" for k, v in kwargs.items())} WHERE index = {message_id}"""
)
diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json
index c4a1ee671..c6a901d2f 100644
--- a/src/frontend/package-lock.json
+++ b/src/frontend/package-lock.json
@@ -64,7 +64,7 @@
"react-icons": "^5.0.1",
"react-laag": "^2.0.5",
"react-markdown": "^8.0.7",
- "react-pdf": "^7.7.1",
+ "react-pdf": "^9.0.0",
"react-router-dom": "^6.15.0",
"react-syntax-highlighter": "^15.5.0",
"react18-json-view": "^0.2.3",
@@ -481,6 +481,7 @@
},
"node_modules/@clack/prompts/node_modules/is-unicode-supported": {
"version": "1.3.0",
+ "extraneous": true,
"inBundle": true,
"license": "MIT",
"engines": {
@@ -10238,25 +10239,25 @@
"node": ">=8"
}
},
- "node_modules/path2d-polyfill": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/path2d-polyfill/-/path2d-polyfill-2.0.1.tgz",
- "integrity": "sha512-ad/3bsalbbWhmBo0D6FZ4RNMwsLsPpL6gnvhuSaU5Vm7b06Kr5ubSltQQ0T7YKsiJQO+g22zJ4dJKNTXIyOXtA==",
+ "node_modules/path2d": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.0.tgz",
+ "integrity": "sha512-KdPAykQX6kmLSOO6Jpu2KNcCED7CKjmaBNGGNuctOsG0hgYO1OdYQaan6cYXJiG0WmXOwZZPILPBimu5QAIw3A==",
"optional": true,
"engines": {
- "node": ">=8"
+ "node": ">=6"
}
},
"node_modules/pdfjs-dist": {
- "version": "3.11.174",
- "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-3.11.174.tgz",
- "integrity": "sha512-TdTZPf1trZ8/UFu5Cx/GXB7GZM30LT+wWUNfsi6Bq8ePLnb+woNKtDymI2mxZYBpMbonNFqKmiz684DIfnd8dA==",
+ "version": "4.3.136",
+ "resolved": "https://registry.npmjs.org/pdfjs-dist/-/pdfjs-dist-4.3.136.tgz",
+ "integrity": "sha512-gzfnt1qc4yA+U46golPGYtU4WM2ssqP2MvFjKga8GEKOrEnzRPrA/9jogLLPYHiA3sGBPJ+p7BdAq+ytmw3jEg==",
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"canvas": "^2.11.2",
- "path2d-polyfill": "^2.0.1"
+ "path2d": "^0.2.0"
}
},
"node_modules/peek-readable": {
@@ -11094,17 +11095,16 @@
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
},
"node_modules/react-pdf": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-7.7.3.tgz",
- "integrity": "sha512-a2VfDl8hiGjugpqezBTUzJHYLNB7IS7a2t7GD52xMI9xHg8LdVaTMsnM9ZlNmKadnStT/tvX5IfV0yLn+JvYmw==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/react-pdf/-/react-pdf-9.0.0.tgz",
+ "integrity": "sha512-J+pza8R2p9oNEOJOHIQJI4o5rFK7ji7bBl2IvsHvz1OOyphvuzVDo5tOJwWAFAbxYauCH3Kt8jOvcMJUOpxYZQ==",
"dependencies": {
"clsx": "^2.0.0",
"dequal": "^2.0.3",
"make-cancellable-promise": "^1.3.1",
"make-event-props": "^1.6.0",
- "merge-refs": "^1.2.1",
- "pdfjs-dist": "3.11.174",
- "prop-types": "^15.6.2",
+ "merge-refs": "^1.3.0",
+ "pdfjs-dist": "4.3.136",
"tiny-invariant": "^1.0.0",
"warning": "^4.0.0"
},
@@ -11112,9 +11112,9 @@
"url": "https://github.com/wojtekmaj/react-pdf?sponsor=1"
},
"peerDependencies": {
- "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
- "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
+ "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@types/react": {
diff --git a/src/frontend/package.json b/src/frontend/package.json
index ab53c6e0b..bb7efd38d 100644
--- a/src/frontend/package.json
+++ b/src/frontend/package.json
@@ -59,7 +59,7 @@
"react-icons": "^5.0.1",
"react-laag": "^2.0.5",
"react-markdown": "^8.0.7",
- "react-pdf": "^7.7.1",
+ "react-pdf": "^9.0.0",
"react-router-dom": "^6.15.0",
"react-syntax-highlighter": "^15.5.0",
"react18-json-view": "^0.2.3",
diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
index 73fdd6ff8..864a29a2a 100644
--- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx
@@ -39,7 +39,11 @@ import {
scapedJSONStringfy,
} from "../../../../utils/reactflowUtils";
import { nodeColors } from "../../../../utils/styleUtils";
-import { classNames, groupByFamily } from "../../../../utils/utils";
+import {
+ classNames,
+ groupByFamily,
+ isThereModal,
+} from "../../../../utils/utils";
import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount";
import useHandleOnNewValue from "../../../hooks/use-handle-new-value";
import useHandleNodeClass from "../../../hooks/use-handle-node-class";
@@ -47,6 +51,8 @@ import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-butto
import TooltipRenderComponent from "../tooltipRenderComponent";
import { TEXT_FIELD_TYPES } from "./constants";
import OutputModal from "../outputModal";
+import { useShortcutsStore } from "../../../../stores/shortcuts";
+import { useHotkeys } from "react-hotkeys-hook";
export default function ParameterComponent({
left,
@@ -63,6 +69,7 @@ export default function ParameterComponent({
proxy,
showNode,
index = "",
+ selected,
}: ParameterComponentType): JSX.Element {
const ref = useRef(null);
const refHtml = useRef(null);
@@ -92,6 +99,19 @@ export default function ParameterComponent({
"unknown"
);
+ const preventDefault = true;
+
+ function handleOutputWShortcut() {
+ if (!displayOutputPreview || unknownOutput) return;
+ if (isThereModal() && !openOutputModal) return;
+ if (selected && !left) {
+ setOpenOutputModal((state) => !state);
+ }
+ }
+
+ const output = useShortcutsStore((state) => state.output);
+ useHotkeys(output, handleOutputWShortcut, { preventDefault });
+
const { handleOnNewValue: handleOnNewValueHook } = useHandleOnNewValue(
data,
name,
diff --git a/src/frontend/src/CustomNodes/GenericNode/index.tsx b/src/frontend/src/CustomNodes/GenericNode/index.tsx
index 261f1230c..bcb14e890 100644
--- a/src/frontend/src/CustomNodes/GenericNode/index.tsx
+++ b/src/frontend/src/CustomNodes/GenericNode/index.tsx
@@ -38,6 +38,7 @@ import useValidationStatusString from "../hooks/use-validation-status-string";
import getFieldTitle from "../utils/get-field-title";
import sortFields from "../utils/sort-fields";
import ParameterComponent from "./components/parameterComponent";
+import { useHotkeys } from "react-hotkeys-hook";
export default function GenericNode({
data,
@@ -49,6 +50,7 @@ export default function GenericNode({
xPos?: number;
yPos?: number;
}): JSX.Element {
+ const preventDefault = true;
const types = useTypesStore((state) => state.types);
const templates = useTypesStore((state) => state.templates);
const deleteNode = useFlowStore((state) => state.deleteNode);
@@ -232,6 +234,25 @@ export default function GenericNode({
}
};
+ function handleUpdateCodeWShortcut() {
+ if (isOutdated && selected) {
+ handleUpdateCode();
+ }
+ }
+
+ function handlePlayWShortcut() {
+ if (buildStatus === BuildStatus.BUILDING || isBuilding || !selected) return;
+ setValidationStatus(null);
+ console.log(data.node?.display_name);
+ buildFlow({ stopNodeId: data.id });
+ }
+
+ const update = useShortcutsStore((state) => state.update);
+ const play = useShortcutsStore((state) => state.play);
+
+ useHotkeys(update, handleUpdateCodeWShortcut, { preventDefault });
+ useHotkeys(play, handlePlayWShortcut, { preventDefault });
+
const shortcuts = useShortcutsStore((state) => state.shortcuts);
const memoizedNodeToolbarComponent = useMemo(() => {
@@ -393,6 +414,7 @@ export default function GenericNode({
data.node!.template[templateField].show &&
!data.node!.template[templateField].advanced && (
{data.node!.base_classes.length > 0 && (
+
{isMac ? (
-
+
) : (
filteredShortcut[0]
)}
-
+
{filteredShortcut.map((key, idx) => {
if (idx > 0) {
- return {key.toUpperCase()} ;
+ return {key.toUpperCase()} ;
}
})}
- >
+
) : (
- <>
+
{shortcutWPlus[0].toLowerCase() === "space" ? (
"Space"
) : shortcutWPlus[0].length <= 1 ? (
shortcutWPlus[0]
) : isMac ? (
-
+
) : (
shortcutWPlus[0]
)}
{shortcutWPlus.map((key, idx) => {
if (idx > 0) {
- return {key.toUpperCase()} ;
+ return {key.toUpperCase()} ;
}
})}
- >
+
);
}
diff --git a/src/frontend/src/constants/constants.ts b/src/frontend/src/constants/constants.ts
index df003c021..67c986bce 100644
--- a/src/frontend/src/constants/constants.ts
+++ b/src/frontend/src/constants/constants.ts
@@ -758,7 +758,7 @@ export const defaultShortcuts = [
shortcut: `${IS_MAC ? "Cmd" : "Ctrl"} + D`,
},
{
- name: "Share",
+ name: "Component Share",
shortcut: `${IS_MAC ? "Cmd" : "Ctrl"} + Shift + S`,
},
{
@@ -799,7 +799,7 @@ export const defaultShortcuts = [
},
{
name: "API",
- shortcut: `${IS_MAC ? "Cmd" : "Ctrl"} + R`,
+ shortcut: `R`,
},
{
name: "Download",
@@ -817,6 +817,14 @@ export const defaultShortcuts = [
name: "Flow Share",
shortcut: `${IS_MAC ? "Cmd" : "Ctrl"} + B`,
},
+ {
+ name: "Play",
+ shortcut: `P`,
+ },
+ {
+ name: "Output Inspection",
+ shortcut: `O`,
+ },
];
export const DEFAULT_TABLE_ALERT_MSG = `Oops! It seems there's no data to display right now. Please check back later.`;
diff --git a/src/frontend/src/icons/Cassandra/Cassandra.jsx b/src/frontend/src/icons/Cassandra/Cassandra.jsx
new file mode 100644
index 000000000..9a8d48d38
--- /dev/null
+++ b/src/frontend/src/icons/Cassandra/Cassandra.jsx
@@ -0,0 +1,73 @@
+const CassandraSVG = (props) => (
+
+);
+export default CassandraSVG;
diff --git a/src/frontend/src/icons/Cassandra/cassandra.svg b/src/frontend/src/icons/Cassandra/cassandra.svg
new file mode 100644
index 000000000..6d6cdf024
--- /dev/null
+++ b/src/frontend/src/icons/Cassandra/cassandra.svg
@@ -0,0 +1,35 @@
+
+
\ No newline at end of file
diff --git a/src/frontend/src/icons/Cassandra/index.tsx b/src/frontend/src/icons/Cassandra/index.tsx
new file mode 100644
index 000000000..7fe917b72
--- /dev/null
+++ b/src/frontend/src/icons/Cassandra/index.tsx
@@ -0,0 +1,9 @@
+import React, { forwardRef } from "react";
+import CassandraSVG from "./Cassandra";
+
+export const CassandraIcon = forwardRef<
+ SVGSVGElement,
+ React.PropsWithChildren<{}>
+>((props, ref) => {
+ return ;
+});
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 a19ee6a28..9aa946746 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
@@ -2,16 +2,27 @@
* Function to get the python code for the API
* @param {string} flowId - The id of the flow
* @param {boolean} isAuth - If the API is authenticated
- * @param {any[]} tweak - The tweaks
+ * @param {any[]} tweaksBuildedObject - The tweaks
+ * @param {string} [endpointName] - The optional endpoint name
* @returns {string} - The python code
*/
export default function getPythonApiCode(
flowId: string,
isAuth: boolean,
- tweaksBuildedObject,
+ tweaksBuildedObject: any[],
endpointName?: string,
): string {
- const tweaksObject = tweaksBuildedObject[0];
+ let tweaksString = "{}";
+ if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
+ const tweaksObject = tweaksBuildedObject[0];
+ if (!tweaksObject) {
+ throw new Error("expected tweaks");
+ }
+ tweaksString = JSON.stringify(tweaksObject, null, 2)
+ .replace(/true/g, "True")
+ .replace(/false/g, "False");
+ }
+
return `import argparse
import json
from argparse import RawTextHelpFormatter
@@ -34,7 +45,7 @@ ENDPOINT = "${endpointName || ""}" ${
# You can tweak the flow by adding a tweaks dictionary
# e.g {"OpenAI-XXXXX": {"model_name": "gpt-4"}}
-TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
+TWEAKS = ${tweaksString}
def run_flow(message: str,
endpoint: str,
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 ff571b492..734e16bbe 100644
--- a/src/frontend/src/modals/apiModal/utils/get-python-code.tsx
+++ b/src/frontend/src/modals/apiModal/utils/get-python-code.tsx
@@ -1,17 +1,26 @@
/**
* Function to get the python code for the API
* @param {string} flow - The current flow
- * @param {any[]} tweak - The tweaks
+ * @param {any[]} tweaksBuildedObject - The tweaks
* @returns {string} - The python code
*/
export default function getPythonCode(
flowName: string,
- tweaksBuildedObject,
+ tweaksBuildedObject: any[],
): string {
- const tweaksObject = tweaksBuildedObject[0];
+ let tweaksString = "{}";
+ if (tweaksBuildedObject && tweaksBuildedObject.length > 0) {
+ const tweaksObject = tweaksBuildedObject[0];
+ if (!tweaksObject) {
+ throw new Error("expected tweaks");
+ }
+ tweaksString = JSON.stringify(tweaksObject, null, 2)
+ .replace(/true/g, "True")
+ .replace(/false/g, "False");
+ }
return `from langflow.load import run_flow_from_json
-TWEAKS = ${JSON.stringify(tweaksObject, null, 2)}
+TWEAKS = ${tweaksString}
result = run_flow_from_json(flow="${flowName}.json",
input_value="message",
diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
index 761dc9831..90692a853 100644
--- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
+++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx
@@ -171,19 +171,17 @@ export default function NodeToolbarComponent({
const advanced = useShortcutsStore((state) => state.advanced);
const minimize = useShortcutsStore((state) => state.minimize);
- const share = useShortcutsStore((state) => state.share);
+ const component = useShortcutsStore((state) => state.component);
const save = useShortcutsStore((state) => state.save);
const docs = useShortcutsStore((state) => state.docs);
const code = useShortcutsStore((state) => state.code);
const group = useShortcutsStore((state) => state.group);
- const update = useShortcutsStore((state) => state.update);
const download = useShortcutsStore((state) => state.download);
const freeze = useShortcutsStore((state) => state.freeze);
useHotkeys(minimize, handleMinimizeWShortcut, { preventDefault });
- useHotkeys(update, handleUpdateWShortcut, { preventDefault });
useHotkeys(group, handleGroupWShortcut, { preventDefault });
- useHotkeys(share, handleShareWShortcut, { preventDefault });
+ useHotkeys(component, handleShareWShortcut, { preventDefault });
useHotkeys(code, handleCodeWShortcut, { preventDefault });
useHotkeys(advanced, handleAdvancedWShortcut, { preventDefault });
useHotkeys(save, handleSaveWShortcut, { preventDefault });
@@ -356,7 +354,7 @@ export default function NodeToolbarComponent({