Merge branch 'dev' into tailwind-constants

This commit is contained in:
anovazzi1 2023-07-05 20:57:16 -03:00
commit 8b35b4b44e
81 changed files with 645 additions and 459 deletions

View file

@ -1,6 +1,6 @@
# LangFlow Demo Codespace Readme # Langflow Demo Codespace Readme
These instructions will walk you through the process of running a LangFlow demo via GitHub Codespaces. These instructions will walk you through the process of running a Langflow demo via GitHub Codespaces.
## Setup ## Setup

47
.env.example Normal file
View file

@ -0,0 +1,47 @@
# Description: Example of .env file
# Usage: Copy this file to .env and change the values
# according to your needs
# Do not commit .env file to git
# Do not change .env.example file
# Database URL
# Postgres example: LANGFLOW_DATABASE_URL=postgresql://postgres:postgres@localhost:5432/langflow
# SQLite example:
LANGFLOW_DATABASE_URL=sqlite:///./langflow.db
# Cache type
LANGFLOW_LANGCHAIN_CACHE=SQLiteCache
# Server host
# Example: LANGFLOW_HOST=127.0.0.1
LANGFLOW_HOST=
# Worker processes
# Example: LANGFLOW_WORKERS=1
LANGFLOW_WORKERS=
# Server port
# Example: LANGFLOW_PORT=7860
LANGFLOW_PORT=
# Logging level
# Example: LANGFLOW_LOG_LEVEL=critical
LANGFLOW_LOG_LEVEL=
# Path to the log file
# Example: LANGFLOW_LOG_FILE=logs/langflow.log
LANGFLOW_LOG_FILE=
# Path to the frontend directory containing build files
# Example: LANGFLOW_FRONTEND_PATH=/path/to/frontend/build/files
LANGFLOW_FRONTEND_PATH=
# Whether to open the browser after starting the server
# Values: true, false
# Example: LANGFLOW_OPEN_BROWSER=true
LANGFLOW_OPEN_BROWSER=
# Whether to remove API keys from the projects saved in the database
# Values: true, false
# Example: LANGFLOW_REMOVE_API_KEYS=false
LANGFLOW_REMOVE_API_KEYS=

View file

@ -1,6 +1,6 @@
# Contributing to LangFlow # Contributing to Langflow
Hello there! We appreciate your interest in contributing to LangFlow. Hello there! We appreciate your interest in contributing to Langflow.
As an open-source project in a rapidly developing field, we are extremely open As an open-source project in a rapidly developing field, we are extremely open
to contributions, whether it be in the form of a new feature, improved infra, or better documentation. to contributions, whether it be in the form of a new feature, improved infra, or better documentation.
@ -40,7 +40,7 @@ the system we use to tag our issues and pull requests.
### Local development ### Local development
You can develop LangFlow using docker compose, or locally. You can develop Langflow using docker compose, or locally.
We provide a .vscode/launch.json file for debugging the backend in VSCode, which is a lot faster than using docker compose. We provide a .vscode/launch.json file for debugging the backend in VSCode, which is a lot faster than using docker compose.

View file

@ -1,6 +1,6 @@
<!-- Title --> <!-- Title -->
# ⛓️ LangFlow # ⛓️ Langflow
~ An effortless way to experiment and prototype [LangChain](https://github.com/hwchase17/langchain) pipelines ~ ~ An effortless way to experiment and prototype [LangChain](https://github.com/hwchase17/langchain) pipelines ~
@ -16,7 +16,7 @@
<p> <p>
<a href="https://discord.gg/EqksyE2EX9"><img alt="Discord Server" src="https://dcbadge.vercel.app/api/server/EqksyE2EX9?compact=true&style=flat"/></a> <a href="https://discord.gg/EqksyE2EX9"><img alt="Discord Server" src="https://dcbadge.vercel.app/api/server/EqksyE2EX9?compact=true&style=flat"/></a>
<a href="https://huggingface.co/spaces/Logspace/LangFlow"><img src="https://huggingface.co/datasets/huggingface/badges/raw/main/open-in-hf-spaces-sm.svg" alt="HuggingFace Spaces"></a> <a href="https://huggingface.co/spaces/Logspace/Langflow"><img src="https://huggingface.co/datasets/huggingface/badges/raw/main/open-in-hf-spaces-sm.svg" alt="HuggingFace Spaces"></a>
</p> </p>
<a href="https://github.com/logspace-ai/langflow"> <a href="https://github.com/logspace-ai/langflow">
@ -26,9 +26,26 @@
<p> <p>
</p> </p>
## 📦 Installation # Table of Contents
- [⛓️ Langflow](#️-langflow)
- [Table of Contents](#table-of-contents)
- [📦 Installation](#-installation)
- [Locally](#locally)
- [🖥️ Command Line Interface (CLI)](#️-command-line-interface-cli)
- [Usage](#usage)
- [Environment Variables](#environment-variables)
- [Deployment](#deployment)
- [Deploy Langflow on Google Cloud Platform](#deploy-langflow-on-google-cloud-platform)
- [Deploy Langflow on Jina AI Cloud](#deploy-langflow-on-jina-ai-cloud)
- [API Usage](#api-usage)
- [🎨 Creating Flows](#-creating-flows)
- [👋 Contributing](#-contributing)
- [📄 License](#-license)
# 📦 Installation
### <b>Locally</b> ### <b>Locally</b>
You can install LangFlow from pip: You can install Langflow from pip:
```shell ```shell
pip install langflow pip install langflow
@ -41,9 +58,51 @@ python -m langflow
``` ```
or or
```shell ```shell
langflow langflow # or langflow --help
``` ```
# 🖥️ Command Line Interface (CLI)
Langflow provides a command-line interface (CLI) for easy management and configuration.
### Usage
You can run the Langflow using the following command:
```shell
langflow [OPTIONS]
```
Each option is detailed below:
- `--help`: Displays all available options.
- `--host`: Defines the host to bind the server to. Can be set using the `LANGFLOW_HOST` environment variable. The default is `127.0.0.1`.
- `--workers`: Sets the number of worker processes. Can be set using the `LANGFLOW_WORKERS` environment variable. The default is `1`.
- `--timeout`: Sets the worker timeout in seconds. The default is `60`.
- `--port`: Sets the port to listen on. Can be set using the `LANGFLOW_PORT` environment variable. The default is `7860`.
- `--config`: Defines the path to the configuration file. The default is `config.yaml`.
- `--env-file`: Specifies the path to the .env file containing environment variables. The default is `.env`.
- `--log-level`: Defines the logging level. Can be set using the `LANGFLOW_LOG_LEVEL` environment variable. The default is `critical`.
- `--log-file`: Specifies the path to the log file. Can be set using the `LANGFLOW_LOG_FILE` environment variable. The default is `logs/langflow.log`.
- `--cache`: Selects the type of cache to use. Options are `InMemoryCache` and `SQLiteCache`. Can be set using the `LANGFLOW_LANGCHAIN_CACHE` environment variable. The default is `SQLiteCache`.
- `--jcloud/--no-jcloud`: Toggles the option to deploy on Jina AI Cloud. The default is `no-jcloud`.
- `--dev/--no-dev`: Toggles the development mode. The default is `no-dev`.
- `--database-url`: Sets the database URL to connect to. If not provided, a local SQLite database will be used. Can be set using the `LANGFLOW_DATABASE_URL` environment variable.
- `--path`: Specifies the path to the frontend directory containing build files. This option is for development purposes only. Can be set using the `LANGFLOW_FRONTEND_PATH` environment variable.
- `--open-browser/--no-open-browser`: Toggles the option to open the browser after starting the server. Can be set using the `LANGFLOW_OPEN_BROWSER` environment variable. The default is `open-browser`.
- `--remove-api-keys/--no-remove-api-keys`: Toggles the option to remove API keys from the projects saved in the database. Can be set using the `LANGFLOW_REMOVE_API_KEYS` environment variable. The default is `no-remove-api-keys`.
- `--install-completion [bash|zsh|fish|powershell|pwsh]`: Installs completion for the specified shell.
- `--show-completion [bash|zsh|fish|powershell|pwsh]`: Shows completion for the specified shell, allowing you to copy it or customize the installation.
### 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.
A sample `.env` file named `.env.example` is included with the project. Copy this file to a new file named `.env` and replace the example values with your actual settings. If you're setting values in both your OS and the `.env` file, the `.env` settings will take precedence.
# Deployment
### Deploy Langflow on Google Cloud Platform ### Deploy Langflow on Google Cloud Platform
Follow our step-by-step guide to deploy Langflow on Google Cloud Platform (GCP) using Google Cloud Shell. The guide is available in the [**Langflow in Google Cloud Platform**](GCP_DEPLOYMENT.md) document. Follow our step-by-step guide to deploy Langflow on Google Cloud Platform (GCP) using Google Cloud Shell. The guide is available in the [**Langflow in Google Cloud Platform**](GCP_DEPLOYMENT.md) document.
@ -163,7 +222,7 @@ print(run_flow("Your message", flow_id=FLOW_ID, tweaks=TWEAKS))
## 🎨 Creating Flows ## 🎨 Creating Flows
Creating flows with LangFlow is easy. Simply drag sidebar components onto the canvas and connect them together to create your pipeline. LangFlow provides a range of [LangChain components](https://api.python.langchain.com/en/latest/index.html) to choose from, including LLMs, prompt serializers, agents, and chains. Creating flows with Langflow is easy. Simply drag sidebar components onto the canvas and connect them together to create your pipeline. Langflow provides a range of [LangChain components](https://langchain.readthedocs.io/en/latest/reference.html) to choose from, including LLMs, prompt serializers, agents, and chains.
Explore by editing prompt parameters, link chains and agents, track an agent's thought process, and export your flow. Explore by editing prompt parameters, link chains and agents, track an agent's thought process, and export your flow.
@ -176,13 +235,13 @@ from langflow import load_flow_from_json
flow = load_flow_from_json("path/to/flow.json") flow = load_flow_from_json("path/to/flow.json")
# Now you can use it like any chain # Now you can use it like any chain
flow("Hey, have you heard of LangFlow?") flow("Hey, have you heard of Langflow?")
``` ```
## 👋 Contributing ## 👋 Contributing
We welcome contributions from developers of all levels to our open-source project on GitHub. If you'd like to contribute, please check our [contributing guidelines](./CONTRIBUTING.md) and help make LangFlow more accessible. We welcome contributions from developers of all levels to our open-source project on GitHub. If you'd like to contribute, please check our [contributing guidelines](./CONTRIBUTING.md) and help make Langflow more accessible.
Join our [Discord](https://discord.com/invite/EqksyE2EX9) server to ask questions, make suggestions and showcase your projects! 🦾 Join our [Discord](https://discord.com/invite/EqksyE2EX9) server to ask questions, make suggestions and showcase your projects! 🦾
@ -195,4 +254,4 @@ Join our [Discord](https://discord.com/invite/EqksyE2EX9) server to ask question
## 📄 License ## 📄 License
LangFlow is released under the MIT License. See the LICENSE file for details. Langflow is released under the MIT License. See the LICENSE file for details.

319
poetry.lock generated
View file

@ -170,14 +170,14 @@ typing-extensions = ">=4.1.1"
[[package]] [[package]]
name = "anyio" name = "anyio"
version = "3.7.0" version = "3.7.1"
description = "High level compatibility layer for multiple asynchronous event loop implementations" description = "High level compatibility layer for multiple asynchronous event loop implementations"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"}, {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
{file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"}, {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
] ]
[package.dependencies] [package.dependencies]
@ -186,7 +186,7 @@ idna = ">=2.8"
sniffio = ">=1.1" sniffio = ">=1.1"
[package.extras] [package.extras]
doc = ["Sphinx (>=6.1.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme", "sphinxcontrib-jquery"] doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"]
test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (<0.22)"] trio = ["trio (<0.22)"]
@ -955,14 +955,14 @@ test-randomorder = ["pytest-randomly"]
[[package]] [[package]]
name = "ctransformers" name = "ctransformers"
version = "0.2.10" version = "0.2.11"
description = "Python bindings for the Transformer models implemented in C/C++ using GGML library." description = "Python bindings for the Transformer models implemented in C/C++ using GGML library."
category = "main" category = "main"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "ctransformers-0.2.10-py3-none-any.whl", hash = "sha256:912a80859bd252e2a389b4716d44b0663657148a85fbfbe6c5503a7ee69fd235"}, {file = "ctransformers-0.2.11-py3-none-any.whl", hash = "sha256:06aa3b2a42112fb688b0d9a54b9958501af7db8557bda067ffbc43645590c522"},
{file = "ctransformers-0.2.10.tar.gz", hash = "sha256:d82a299690f1494fe93db136f71b1b9b2cd4ada535e2afa07aaee1d180117a2d"}, {file = "ctransformers-0.2.11.tar.gz", hash = "sha256:993a3ba05d37822d0111393ab214856b9fe40d28b48af1306ee63e94e716a4e2"},
] ]
[package.dependencies] [package.dependencies]
@ -1609,14 +1609,14 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]] [[package]]
name = "google-api-python-client" name = "google-api-python-client"
version = "2.91.0" version = "2.92.0"
description = "Google API Client Library for Python" description = "Google API Client Library for Python"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "google-api-python-client-2.91.0.tar.gz", hash = "sha256:d9385ad6e7f95eecd40f7c81e3abfe4b6ad3a84f2c16bcdb66fb7b8dd814ed56"}, {file = "google-api-python-client-2.92.0.tar.gz", hash = "sha256:f38a6e106a7417719715506d36f0a233ec253335e422bda311352866a86c4187"},
{file = "google_api_python_client-2.91.0-py2.py3-none-any.whl", hash = "sha256:6959d21d4b20c0f65c69662ca7b6a8a02fc08f3e7f72d70b28ae3e6e3a5f9ab2"}, {file = "google_api_python_client-2.92.0-py2.py3-none-any.whl", hash = "sha256:e0b74ed5fa9bdb07a66fb030d3f4cae550ed1c07e23600d86450d3c3c5efae51"},
] ]
[package.dependencies] [package.dependencies]
@ -1761,14 +1761,14 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)"]
[[package]] [[package]]
name = "google-cloud-resource-manager" name = "google-cloud-resource-manager"
version = "1.10.1" version = "1.10.2"
description = "Google Cloud Resource Manager API client library" description = "Google Cloud Resource Manager API client library"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "google-cloud-resource-manager-1.10.1.tar.gz", hash = "sha256:c974fb6f9810476cf7b63ea89394c1a8df47f7f2dc2303e728bb74b500bcde67"}, {file = "google-cloud-resource-manager-1.10.2.tar.gz", hash = "sha256:9a7bdd0347ad553376cc66ad317c5223d1ae04bdcf74edcbfcd12605cff7b510"},
{file = "google_cloud_resource_manager-1.10.1-py2.py3-none-any.whl", hash = "sha256:41a2204532f084c707fde0bc1a9bc95c7e0b739d7072dd0b8a25106667a56184"}, {file = "google_cloud_resource_manager-1.10.2-py2.py3-none-any.whl", hash = "sha256:9e074c28326bd1632f1a270c20cfea1ffe98f49cf821033e65bdac55661ffbd5"},
] ]
[package.dependencies] [package.dependencies]
@ -2538,14 +2538,14 @@ files = [
[[package]] [[package]]
name = "ipykernel" name = "ipykernel"
version = "6.23.3" version = "6.24.0"
description = "IPython Kernel for Jupyter" description = "IPython Kernel for Jupyter"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "ipykernel-6.23.3-py3-none-any.whl", hash = "sha256:bc00662dc44d4975b668cdb5fefb725e38e9d8d6e28441a519d043f38994922d"}, {file = "ipykernel-6.24.0-py3-none-any.whl", hash = "sha256:2f5fffc7ad8f1fd5aadb4e171ba9129d9668dbafa374732cf9511ada52d6547f"},
{file = "ipykernel-6.23.3.tar.gz", hash = "sha256:dd4e18116357f36a1e459b3768412371bee764c51844cbf25c4ed1eb9cae4a54"}, {file = "ipykernel-6.24.0.tar.gz", hash = "sha256:29cea0a716b1176d002a61d0b0c851f34536495bc4ef7dd0222c88b41b816123"},
] ]
[package.dependencies] [package.dependencies]
@ -2808,14 +2808,14 @@ websockets = ["websockets"]
[[package]] [[package]]
name = "jina-hubble-sdk" name = "jina-hubble-sdk"
version = "0.38.0" version = "0.39.0"
description = "SDK for Hubble API at Jina AI." description = "SDK for Hubble API at Jina AI."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.7.0"
files = [ files = [
{file = "jina-hubble-sdk-0.38.0.tar.gz", hash = "sha256:1667917ed16d75eddd1e0d3b8e9d78ffd611de59500abeca48b05040c7571c4c"}, {file = "jina-hubble-sdk-0.39.0.tar.gz", hash = "sha256:9021417794a6d3cf3fad8a880cf668a3a986b9d53d5be5fa391aae1767a5b9b0"},
{file = "jina_hubble_sdk-0.38.0-py3-none-any.whl", hash = "sha256:f887f5a5839b530b59393fe56e9b48d406f52a178739d3a5799c8e201bcf4015"}, {file = "jina_hubble_sdk-0.39.0-py3-none-any.whl", hash = "sha256:b0edd4b62d742c27d726d68f65a041b3c4d9aa6b3b9b203d5b0e729904161e3e"},
] ]
[package.dependencies] [package.dependencies]
@ -2973,13 +2973,13 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
[[package]] [[package]]
name = "langchain-serve" name = "langchain-serve"
version = "0.0.49" version = "0.0.52"
description = "Langchain Serve - serve your langchain apps on Jina AI Cloud." description = "Langchain Serve - serve your langchain apps on Jina AI Cloud."
category = "main" category = "main"
optional = true optional = true
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "langchain-serve-0.0.49.tar.gz", hash = "sha256:5dc30276e709e59838c28508228ad2185e264c8877ea70194fa5d2acd44e966d"}, {file = "langchain-serve-0.0.52.tar.gz", hash = "sha256:e69dcf6022423279059ab7ebda025e252aba4d9fd8e3e49776300355dbf85d1c"},
] ]
[package.dependencies] [package.dependencies]
@ -2999,14 +2999,14 @@ test = ["psutil", "pytest", "pytest-asyncio"]
[[package]] [[package]]
name = "langchainplus-sdk" name = "langchainplus-sdk"
version = "0.0.19" version = "0.0.20"
description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langchainplus_sdk-0.0.19-py3-none-any.whl", hash = "sha256:2ee028280ad87063676efa1a0da1aa7801e8becf55b340c29e95cc536c2647f3"}, {file = "langchainplus_sdk-0.0.20-py3-none-any.whl", hash = "sha256:07a869d476755803aa04c4986ce78d00c2fe4ff584c0eaa57d7570c9664188db"},
{file = "langchainplus_sdk-0.0.19.tar.gz", hash = "sha256:8ec11f07c0ce35b164eb3bd7217bfdb9f7c20263508751b1e9e5e12c9960bf45"}, {file = "langchainplus_sdk-0.0.20.tar.gz", hash = "sha256:3d300e2e3290f68cc9d842c059f9458deba60e776c9e790309688cad1bfbb219"},
] ]
[package.dependencies] [package.dependencies]
@ -3070,96 +3070,100 @@ dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegu
[[package]] [[package]]
name = "lxml" name = "lxml"
version = "4.9.2" version = "4.9.3"
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
category = "main" category = "main"
optional = false optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
files = [ files = [
{file = "lxml-4.9.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2"}, {file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"},
{file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892"}, {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"},
{file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a"}, {file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"},
{file = "lxml-4.9.2-cp27-cp27m-win32.whl", hash = "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de"}, {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"},
{file = "lxml-4.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3"}, {file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"},
{file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50"}, {file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"},
{file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975"}, {file = "lxml-4.9.3-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd"},
{file = "lxml-4.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c"}, {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"},
{file = "lxml-4.9.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:85cabf64adec449132e55616e7ca3e1000ab449d1d0f9d7f83146ed5bdcb6d8a"}, {file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"},
{file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4"}, {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"},
{file = "lxml-4.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:1ab8f1f932e8f82355e75dda5413a57612c6ea448069d4fb2e217e9a4bed13d4"}, {file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"},
{file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7"}, {file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"},
{file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184"}, {file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"},
{file = "lxml-4.9.2-cp310-cp310-win32.whl", hash = "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda"}, {file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"},
{file = "lxml-4.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab"}, {file = "lxml-4.9.3-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf"},
{file = "lxml-4.9.2-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c83203addf554215463b59f6399835201999b5e48019dc17f182ed5ad87205c9"}, {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"},
{file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf"}, {file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"},
{file = "lxml-4.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:d6b430a9938a5a5d85fc107d852262ddcd48602c120e3dbb02137c83d212b380"}, {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"},
{file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92"}, {file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"},
{file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1"}, {file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"},
{file = "lxml-4.9.2-cp311-cp311-win32.whl", hash = "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33"}, {file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"},
{file = "lxml-4.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd"}, {file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"},
{file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0"}, {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"},
{file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e"}, {file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"},
{file = "lxml-4.9.2-cp35-cp35m-win32.whl", hash = "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df"}, {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"},
{file = "lxml-4.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5"}, {file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"},
{file = "lxml-4.9.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53"}, {file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:ab323679b8b3030000f2be63e22cdeea5b47ee0abd2d6a1dc0c8103ddaa56cd7"}, {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe"}, {file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f49e52d174375a7def9915c9f06ec4e569d235ad428f70751765f48d5926678c"}, {file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1"}, {file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e"}, {file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"},
{file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74"}, {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5"},
{file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38"}, {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"},
{file = "lxml-4.9.2-cp36-cp36m-win32.whl", hash = "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5"}, {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"},
{file = "lxml-4.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3"}, {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"},
{file = "lxml-4.9.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03"}, {file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:a5da296eb617d18e497bcf0a5c528f5d3b18dadb3619fbdadf4ed2356ef8d941"}, {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726"}, {file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:c9ec3eaf616d67db0764b3bb983962b4f385a1f08304fd30c7283954e6a7869b"}, {file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894"}, {file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45"}, {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601"},
{file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e"}, {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"},
{file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b"}, {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"},
{file = "lxml-4.9.2-cp37-cp37m-win32.whl", hash = "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe"}, {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"},
{file = "lxml-4.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9"}, {file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"},
{file = "lxml-4.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8"}, {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:821b7f59b99551c69c85a6039c65b75f5683bdc63270fec660f75da67469ca24"}, {file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889"}, {file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:8e20cb5a47247e383cf4ff523205060991021233ebd6f924bca927fcf25cf86f"}, {file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03"}, {file = "lxml-4.9.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c"}, {file = "lxml-4.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"},
{file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f"}, {file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"},
{file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457"}, {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"},
{file = "lxml-4.9.2-cp38-cp38-win32.whl", hash = "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b"}, {file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"},
{file = "lxml-4.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7"}, {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"},
{file = "lxml-4.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1"}, {file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:090c6543d3696cbe15b4ac6e175e576bcc3f1ccfbba970061b7300b0c15a2140"}, {file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4"}, {file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:5b4545b8a40478183ac06c073e81a5ce4cf01bf1734962577cf2bb569a5b3bbf"}, {file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947"}, {file = "lxml-4.9.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5"}, {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"},
{file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5"}, {file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"},
{file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2"}, {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"},
{file = "lxml-4.9.2-cp39-cp39-win32.whl", hash = "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1"}, {file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"},
{file = "lxml-4.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f"}, {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"},
{file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b264171e3143d842ded311b7dccd46ff9ef34247129ff5bf5066123c55c2431c"}, {file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"},
{file = "lxml-4.9.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0dc313ef231edf866912e9d8f5a042ddab56c752619e92dfd3a2c277e6a7299a"}, {file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"},
{file = "lxml-4.9.2-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419"}, {file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"},
{file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0f2b1e0d79180f344ff9f321327b005ca043a50ece8713de61d1cb383fb8ac05"}, {file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"},
{file = "lxml-4.9.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7b770ed79542ed52c519119473898198761d78beb24b107acf3ad65deae61f1f"}, {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0"},
{file = "lxml-4.9.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9"}, {file = "lxml-4.9.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"},
{file = "lxml-4.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5"}, {file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"},
{file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:b23e19989c355ca854276178a0463951a653309fb8e57ce674497f2d9f208746"}, {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7"},
{file = "lxml-4.9.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:01d36c05f4afb8f7c20fd9ed5badca32a2029b93b1750f571ccc0b142531caf7"}, {file = "lxml-4.9.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"},
{file = "lxml-4.9.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409"}, {file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"},
{file = "lxml-4.9.2.tar.gz", hash = "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67"}, {file = "lxml-4.9.3-pp39-pypy39_pp73-macosx_11_0_x86_64.whl", hash = "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4"},
{file = "lxml-4.9.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9"},
{file = "lxml-4.9.3.tar.gz", hash = "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c"},
] ]
[package.extras] [package.extras]
cssselect = ["cssselect (>=0.7)"] cssselect = ["cssselect (>=0.7)"]
html5 = ["html5lib"] html5 = ["html5lib"]
htmlsoup = ["BeautifulSoup4"] htmlsoup = ["BeautifulSoup4"]
source = ["Cython (>=0.29.7)"] source = ["Cython (>=0.29.35)"]
[[package]] [[package]]
name = "lz4" name = "lz4"
@ -3231,14 +3235,14 @@ testing = ["coverage", "pyyaml"]
[[package]] [[package]]
name = "markdown-it-py" name = "markdown-it-py"
version = "2.2.0" version = "3.0.0"
description = "Python port of markdown-it. Markdown parsing, done right!" description = "Python port of markdown-it. Markdown parsing, done right!"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.8"
files = [ files = [
{file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
{file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
] ]
[package.dependencies] [package.dependencies]
@ -3253,7 +3257,7 @@ compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0
linkify = ["linkify-it-py (>=1,<3)"] linkify = ["linkify-it-py (>=1,<3)"]
plugins = ["mdit-py-plugins"] plugins = ["mdit-py-plugins"]
profiling = ["gprof2dot"] profiling = ["gprof2dot"]
rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
[[package]] [[package]]
@ -4625,14 +4629,14 @@ twisted = ["twisted"]
[[package]] [[package]]
name = "prompt-toolkit" name = "prompt-toolkit"
version = "3.0.38" version = "3.0.39"
description = "Library for building powerful interactive command lines in Python" description = "Library for building powerful interactive command lines in Python"
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.7.0"
files = [ files = [
{file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"},
{file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"},
] ]
[package.dependencies] [package.dependencies]
@ -5029,48 +5033,48 @@ files = [
[[package]] [[package]]
name = "pydantic" name = "pydantic"
version = "1.10.10" version = "1.10.11"
description = "Data validation and settings management using python type hints" description = "Data validation and settings management using python type hints"
category = "main" category = "main"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pydantic-1.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adad1ee4ab9888f12dac2529276704e719efcf472e38df7813f5284db699b4ec"}, {file = "pydantic-1.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ff44c5e89315b15ff1f7fdaf9853770b810936d6b01a7bcecaa227d2f8fe444f"},
{file = "pydantic-1.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a7db03339893feef2092ff7b1afc9497beed15ebd4af84c3042a74abce02d48"}, {file = "pydantic-1.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c098d4ab5e2d5b3984d3cb2527e2d6099d3de85630c8934efcfdc348a9760e"},
{file = "pydantic-1.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b3714b97ff84b2689654851c2426389bcabfac9080617bcf4306c69db606f6"}, {file = "pydantic-1.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16928fdc9cb273c6af00d9d5045434c39afba5f42325fb990add2c241402d151"},
{file = "pydantic-1.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edfdf0a5abc5c9bf2052ebaec20e67abd52e92d257e4f2d30e02c354ed3e6030"}, {file = "pydantic-1.10.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0588788a9a85f3e5e9ebca14211a496409cb3deca5b6971ff37c556d581854e7"},
{file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a3b30fd255eeeb63caa9483502ba96b7795ce5bf895c6a179b3d909d9f53a6"}, {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9baf78b31da2dc3d3f346ef18e58ec5f12f5aaa17ac517e2ffd026a92a87588"},
{file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db4c7f7e60ca6f7d6c1785070f3e5771fcb9b2d88546e334d2f2c3934d949028"}, {file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:373c0840f5c2b5b1ccadd9286782852b901055998136287828731868027a724f"},
{file = "pydantic-1.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:a2d5be50ac4a0976817144c7d653e34df2f9436d15555189f5b6f61161d64183"}, {file = "pydantic-1.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:c3339a46bbe6013ef7bdd2844679bfe500347ac5742cd4019a88312aa58a9847"},
{file = "pydantic-1.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:566a04ba755e8f701b074ffb134ddb4d429f75d5dced3fbd829a527aafe74c71"}, {file = "pydantic-1.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08a6c32e1c3809fbc49debb96bf833164f3438b3696abf0fbeceb417d123e6eb"},
{file = "pydantic-1.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f79db3652ed743309f116ba863dae0c974a41b688242482638b892246b7db21d"}, {file = "pydantic-1.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a451ccab49971af043ec4e0d207cbc8cbe53dbf148ef9f19599024076fe9c25b"},
{file = "pydantic-1.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62376890b819bebe3c717a9ac841a532988372b7e600e76f75c9f7c128219d5"}, {file = "pydantic-1.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b02d24f7b2b365fed586ed73582c20f353a4c50e4be9ba2c57ab96f8091ddae"},
{file = "pydantic-1.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4870f13a4fafd5bc3e93cff3169222534fad867918b188e83ee0496452978437"}, {file = "pydantic-1.10.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f34739a89260dfa420aa3cbd069fbcc794b25bbe5c0a214f8fb29e363484b66"},
{file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:990027e77cda6072a566e433b6962ca3b96b4f3ae8bd54748e9d62a58284d9d7"}, {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e297897eb4bebde985f72a46a7552a7556a3dd11e7f76acda0c1093e3dbcf216"},
{file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8c40964596809eb616d94f9c7944511f620a1103d63d5510440ed2908fc410af"}, {file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d185819a7a059550ecb85d5134e7d40f2565f3dd94cfd870132c5f91a89cf58c"},
{file = "pydantic-1.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:ea9eebc2ebcba3717e77cdeee3f6203ffc0e78db5f7482c68b1293e8cc156e5e"}, {file = "pydantic-1.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:4400015f15c9b464c9db2d5d951b6a780102cfa5870f2c036d37c23b56f7fc1b"},
{file = "pydantic-1.10.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:762aa598f79b4cac2f275d13336b2dd8662febee2a9c450a49a2ab3bec4b385f"}, {file = "pydantic-1.10.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2417de68290434461a266271fc57274a138510dca19982336639484c73a07af6"},
{file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dab5219659f95e357d98d70577b361383057fb4414cfdb587014a5f5c595f7b"}, {file = "pydantic-1.10.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:331c031ba1554b974c98679bd0780d89670d6fd6f53f5d70b10bdc9addee1713"},
{file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3d4ee957a727ccb5a36f1b0a6dbd9fad5dedd2a41eada99a8df55c12896e18d"}, {file = "pydantic-1.10.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8268a735a14c308923e8958363e3a3404f6834bb98c11f5ab43251a4e410170c"},
{file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b69f9138dec566962ec65623c9d57bee44412d2fc71065a5f3ebb3820bdeee96"}, {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:44e51ba599c3ef227e168424e220cd3e544288c57829520dc90ea9cb190c3248"},
{file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7aa75d1bd9cc275cf9782f50f60cddaf74cbaae19b6ada2a28e737edac420312"}, {file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d7781f1d13b19700b7949c5a639c764a077cbbdd4322ed505b449d3ca8edcb36"},
{file = "pydantic-1.10.10-cp37-cp37m-win_amd64.whl", hash = "sha256:9f62a727f5c590c78c2d12fda302d1895141b767c6488fe623098f8792255fe5"}, {file = "pydantic-1.10.11-cp37-cp37m-win_amd64.whl", hash = "sha256:7522a7666157aa22b812ce14c827574ddccc94f361237ca6ea8bb0d5c38f1629"},
{file = "pydantic-1.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aac218feb4af73db8417ca7518fb3bade4534fcca6e3fb00f84966811dd94450"}, {file = "pydantic-1.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc64eab9b19cd794a380179ac0e6752335e9555d214cfcb755820333c0784cb3"},
{file = "pydantic-1.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88546dc10a40b5b52cae87d64666787aeb2878f9a9b37825aedc2f362e7ae1da"}, {file = "pydantic-1.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8dc77064471780262b6a68fe67e013298d130414d5aaf9b562c33987dbd2cf4f"},
{file = "pydantic-1.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c41bbaae89e32fc582448e71974de738c055aef5ab474fb25692981a08df808a"}, {file = "pydantic-1.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe429898f2c9dd209bd0632a606bddc06f8bce081bbd03d1c775a45886e2c1cb"},
{file = "pydantic-1.10.10-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b71bd504d1573b0b722ae536e8ffb796bedeef978979d076bf206e77dcc55a5"}, {file = "pydantic-1.10.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:192c608ad002a748e4a0bed2ddbcd98f9b56df50a7c24d9a931a8c5dd053bd3d"},
{file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e088e3865a2270ecbc369924cd7d9fbc565667d9158e7f304e4097ebb9cf98dd"}, {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef55392ec4bb5721f4ded1096241e4b7151ba6d50a50a80a2526c854f42e6a2f"},
{file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3403a090db45d4027d2344859d86eb797484dfda0706cf87af79ace6a35274ef"}, {file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:41e0bb6efe86281623abbeeb0be64eab740c865388ee934cd3e6a358784aca6e"},
{file = "pydantic-1.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:e0014e29637125f4997c174dd6167407162d7af0da73414a9340461ea8573252"}, {file = "pydantic-1.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:265a60da42f9f27e0b1014eab8acd3e53bd0bad5c5b4884e98a55f8f596b2c19"},
{file = "pydantic-1.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9965e49c6905840e526e5429b09e4c154355b6ecc0a2f05492eda2928190311d"}, {file = "pydantic-1.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:469adf96c8e2c2bbfa655fc7735a2a82f4c543d9fee97bd113a7fb509bf5e622"},
{file = "pydantic-1.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:748d10ab6089c5d196e1c8be9de48274f71457b01e59736f7a09c9dc34f51887"}, {file = "pydantic-1.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e6cbfbd010b14c8a905a7b10f9fe090068d1744d46f9e0c021db28daeb8b6de1"},
{file = "pydantic-1.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86936c383f7c38fd26d35107eb669c85d8f46dfceae873264d9bab46fe1c7dde"}, {file = "pydantic-1.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abade85268cc92dff86d6effcd917893130f0ff516f3d637f50dadc22ae93999"},
{file = "pydantic-1.10.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a26841be620309a9697f5b1ffc47dce74909e350c5315ccdac7a853484d468a"}, {file = "pydantic-1.10.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e9738b0f2e6c70f44ee0de53f2089d6002b10c33264abee07bdb5c7f03038303"},
{file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:409b810f387610cc7405ab2fa6f62bdf7ea485311845a242ebc0bd0496e7e5ac"}, {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:787cf23e5a0cde753f2eabac1b2e73ae3844eb873fd1f5bdbff3048d8dbb7604"},
{file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ce937a2a2c020bcad1c9fde02892392a1123de6dda906ddba62bfe8f3e5989a2"}, {file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:174899023337b9fc685ac8adaa7b047050616136ccd30e9070627c1aaab53a13"},
{file = "pydantic-1.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:37ebddef68370e6f26243acc94de56d291e01227a67b2ace26ea3543cf53dd5f"}, {file = "pydantic-1.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:1954f8778489a04b245a1e7b8b22a9d3ea8ef49337285693cf6959e4b757535e"},
{file = "pydantic-1.10.10-py3-none-any.whl", hash = "sha256:a5939ec826f7faec434e2d406ff5e4eaf1716eb1f247d68cd3d0b3612f7b4c8a"}, {file = "pydantic-1.10.11-py3-none-any.whl", hash = "sha256:008c5e266c8aada206d0627a011504e14268a62091450210eda7c07fabe6963e"},
{file = "pydantic-1.10.10.tar.gz", hash = "sha256:3b8d5bd97886f9eb59260594207c9f57dce14a6f869c6ceea90188715d29921a"}, {file = "pydantic-1.10.11.tar.gz", hash = "sha256:f66d479cf7eb331372c470614be6511eae96f1f120344c25f3f9bb59fb1b5528"},
] ]
[package.dependencies] [package.dependencies]
@ -6599,25 +6603,22 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"]
[[package]] [[package]]
name = "textual" name = "textual"
version = "0.28.1" version = "0.29.0"
description = "Modern Text User Interface framework" description = "Modern Text User Interface framework"
category = "main" category = "main"
optional = true optional = true
python-versions = ">=3.7,<4.0" python-versions = ">=3.7,<4.0"
files = [ files = [
{file = "textual-0.28.1-py3-none-any.whl", hash = "sha256:cb6f6230fea390178f8e727d2f9e542337a655549ea44331e22336da799a900f"}, {file = "textual-0.29.0-py3-none-any.whl", hash = "sha256:949fd8f16a412404ba785605dda1e2fab8166656e4d29d4177ec63cd73ba83d4"},
{file = "textual-0.28.1.tar.gz", hash = "sha256:f63a873d810b5d01f7318d8eb8f706d530550f3a90a6892628d17d47ecefcd41"}, {file = "textual-0.29.0.tar.gz", hash = "sha256:7eb87b6d007dc9bd08e00e893b860ecb7a11ca815c8866db39fe17ec547e2fcf"},
] ]
[package.dependencies] [package.dependencies]
importlib-metadata = ">=4.11.3" importlib-metadata = ">=4.11.3"
markdown-it-py = {version = ">=2.1.0,<3.0.0", extras = ["linkify", "plugins"]} markdown-it-py = {version = ">=2.1.0", extras = ["linkify", "plugins"]}
rich = ">=13.3.3" rich = ">=13.3.3"
typing-extensions = ">=4.4.0,<5.0.0" typing-extensions = ">=4.4.0,<5.0.0"
[package.extras]
dev = ["aiohttp (>=3.8.1)", "click (>=8.1.2)", "msgpack (>=1.0.3)"]
[[package]] [[package]]
name = "threadpoolctl" name = "threadpoolctl"
version = "3.1.0" version = "3.1.0"
@ -7046,14 +7047,14 @@ files = [
[[package]] [[package]]
name = "types-pillow" name = "types-pillow"
version = "9.5.0.5" version = "9.5.0.6"
description = "Typing stubs for Pillow" description = "Typing stubs for Pillow"
category = "dev" category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "types-Pillow-9.5.0.5.tar.gz", hash = "sha256:de9877aa1e6226b6479459ca84df02fd7e999b970c79cfee3b8298840336e77c"}, {file = "types-Pillow-9.5.0.6.tar.gz", hash = "sha256:6a0cad40686e5c35fe7ada70f52bd3970395d31ece33486609e5420e820a9e4e"},
{file = "types_Pillow-9.5.0.5-py3-none-any.whl", hash = "sha256:2b17f95c5c16e4962e4032bdb95494766a85569fa278ee21e5fcbbd318e9ccd2"}, {file = "types_Pillow-9.5.0.6-py3-none-any.whl", hash = "sha256:1d238abaa9d529b04941d805b7f4d3f7df30702bb14521ec507617f117406fb4"},
] ]
[[package]] [[package]]
@ -7831,4 +7832,4 @@ deploy = ["langchain-serve"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = ">=3.9,<3.11" python-versions = ">=3.9,<3.11"
content-hash = "814dc6b89b345e3ea08c7b7dc1fb29e3f8484070e3ad67030eb67566b33f12b0" content-hash = "e25e43fde8f96f57beab702ac4c51cb3e569b81f85c540a7b4b5fb7b6388d04e"

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "langflow" name = "langflow"
version = "0.2.11" version = "0.2.13"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
authors = ["Logspace <contact@logspace.ai>"] authors = ["Logspace <contact@logspace.ai>"]
maintainers = [ maintainers = [
@ -48,7 +48,7 @@ psycopg2-binary = "^2.9.6"
pyarrow = "^12.0.0" pyarrow = "^12.0.0"
tiktoken = "~0.4.0" tiktoken = "~0.4.0"
wikipedia = "^1.4.0" wikipedia = "^1.4.0"
langchain-serve = { version = ">0.0.47", optional = true } langchain-serve = { version = ">0.0.51", optional = true }
qdrant-client = "^1.3.0" qdrant-client = "^1.3.0"
websockets = "^10.3" websockets = "^10.3"
weaviate-client = "^3.21.0" weaviate-client = "^3.21.0"

View file

@ -1,6 +1,6 @@
from importlib import metadata from importlib import metadata
from langflow.cache import cache_manager from langflow.cache import cache_manager # noqa: E402
from langflow.processing.process import load_flow_from_json from langflow.processing.process import load_flow_from_json # noqa: E402
try: try:
__version__ = metadata.version(__package__) __version__ = metadata.version(__package__)
@ -9,4 +9,5 @@ except metadata.PackageNotFoundError:
__version__ = "" __version__ = ""
del metadata # optional, avoids polluting the results of dir(__package__) del metadata # optional, avoids polluting the results of dir(__package__)
__all__ = ["load_flow_from_json", "cache_manager"] __all__ = ["load_flow_from_json", "cache_manager"]

View file

@ -1,3 +1,4 @@
import os
import sys import sys
import time import time
import httpx import httpx
@ -33,6 +34,10 @@ def update_settings(
remove_api_keys: bool = False, remove_api_keys: bool = False,
): ):
"""Update the settings from a config file.""" """Update the settings from a config file."""
# Check for database_url in the environment variables
database_url = database_url or os.getenv("langflow_database_url")
if config: if config:
settings.update_from_yaml(config, dev=dev) settings.update_from_yaml(config, dev=dev)
if database_url: if database_url:
@ -43,6 +48,26 @@ def update_settings(
settings.update_settings(cache=cache) settings.update_settings(cache=cache)
def load_params():
"""
Load the parameters from the environment variables.
"""
global_vars = globals()
for key, value in global_vars.items():
env_key = f"LANGFLOW_{key.upper()}"
if env_key in os.environ:
if isinstance(value, bool):
# Handle booleans
global_vars[key] = os.getenv(env_key, str(value)).lower() == "true"
elif isinstance(value, int):
# Handle integers
global_vars[key] = int(os.getenv(env_key, str(value)))
elif isinstance(value, str) or value is None:
# Handle strings and None values
global_vars[key] = os.getenv(env_key, str(value))
def serve_on_jcloud(): def serve_on_jcloud():
""" """
Deploy Langflow server on Jina AI Cloud Deploy Langflow server on Jina AI Cloud
@ -91,19 +116,27 @@ def serve_on_jcloud():
@app.command() @app.command()
def serve( def serve(
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."), host: str = typer.Option(
workers: int = typer.Option(1, help="Number of worker processes."), "127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"
),
workers: int = typer.Option(
1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"
),
timeout: int = typer.Option(60, help="Worker timeout in seconds."), timeout: int = typer.Option(60, help="Worker timeout in seconds."),
port: int = typer.Option(7860, help="Port to listen on."), port: int = typer.Option(7860, help="Port to listen on.", envvar="LANGFLOW_PORT"),
config: str = typer.Option("config.yaml", help="Path to the configuration file."), config: str = typer.Option("config.yaml", help="Path to the configuration file."),
# .env file param # .env file param
env_file: Path = typer.Option( env_file: Path = typer.Option(
".env", help="Path to the .env file containing environment variables." ".env", help="Path to the .env file containing environment variables."
), ),
log_level: str = typer.Option("critical", help="Logging level."), log_level: str = typer.Option(
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."), "critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"
cache: str = typer.Argument( ),
envvar="LANGCHAIN_CACHE", log_file: Path = typer.Option(
"logs/langflow.log", help="Path to the log file.", envvar="LANGFLOW_LOG_FILE"
),
cache: str = typer.Option(
envvar="LANGFLOW_LANGCHAIN_CACHE",
help="Type of cache to use. (InMemoryCache, SQLiteCache)", help="Type of cache to use. (InMemoryCache, SQLiteCache)",
default="SQLiteCache", default="SQLiteCache",
), ),
@ -112,27 +145,35 @@ def serve(
database_url: str = typer.Option( database_url: str = typer.Option(
None, None,
help="Database URL to connect to. If not provided, a local SQLite database will be used.", help="Database URL to connect to. If not provided, a local SQLite database will be used.",
envvar="LANGFLOW_DATABASE_URL",
), ),
path: str = typer.Option( path: str = typer.Option(
None, None,
help="Path to the frontend directory containing build files. This is for development purposes only.", help="Path to the frontend directory containing build files. This is for development purposes only.",
envvar="LANGFLOW_FRONTEND_PATH",
), ),
open_browser: bool = typer.Option( open_browser: bool = typer.Option(
True, help="Open the browser after starting the server." True,
help="Open the browser after starting the server.",
envvar="LANGFLOW_OPEN_BROWSER",
), ),
remove_api_keys: bool = typer.Option( remove_api_keys: bool = typer.Option(
False, help="Remove API keys from the projects saved in the database." False,
help="Remove API keys from the projects saved in the database.",
envvar="LANGFLOW_REMOVE_API_KEYS",
), ),
): ):
""" """
Run the Langflow server. Run the Langflow server.
""" """
# override env variables with .env file
if env_file:
load_dotenv(env_file, override=True)
load_params()
if jcloud: if jcloud:
return serve_on_jcloud() return serve_on_jcloud()
load_dotenv(env_file)
configure(log_level=log_level, log_file=log_file) configure(log_level=log_level, log_file=log_file)
update_settings( update_settings(
config, config,
@ -224,7 +265,7 @@ def get_free_port(port):
def print_banner(host, port): def print_banner(host, port):
# console = Console() # console = Console()
word = "LangFlow" word = "Langflow"
colors = ["#3300cc"] colors = ["#3300cc"]
styled_word = "" styled_word = ""

View file

@ -23,7 +23,7 @@ class GraphData(BaseModel):
class ExportedFlow(BaseModel): class ExportedFlow(BaseModel):
"""Exported flow from LangFlow.""" """Exported flow from Langflow."""
description: str description: str
name: str name: str

View file

@ -2,17 +2,34 @@ from langflow.settings import settings
from sqlmodel import SQLModel, Session, create_engine from sqlmodel import SQLModel, Session, create_engine
from langflow.utils.logger import logger from langflow.utils.logger import logger
if settings.database_url.startswith("sqlite"): if settings.database_url and settings.database_url.startswith("sqlite"):
connect_args = {"check_same_thread": False} connect_args = {"check_same_thread": False}
else: else:
connect_args = {} connect_args = {}
if not settings.database_url:
raise RuntimeError("No database_url provided")
engine = create_engine(settings.database_url, connect_args=connect_args) engine = create_engine(settings.database_url, connect_args=connect_args)
def create_db_and_tables(): def create_db_and_tables():
logger.debug("Creating database and tables") logger.debug("Creating database and tables")
SQLModel.metadata.create_all(engine) try:
logger.debug("Database and tables created") SQLModel.metadata.create_all(engine)
except Exception as exc:
logger.error(f"Error creating database and tables: {exc}")
raise RuntimeError("Error creating database and tables") from exc
# Now check if the table Flow exists, if not, something went wrong
# and we need to create the tables again.
from sqlalchemy import inspect
inspector = inspect(engine)
if "flow" not in inspector.get_table_names():
logger.error("Something went wrong creating the database and tables.")
logger.error("Please check your database settings.")
raise RuntimeError("Something went wrong creating the database and tables.")
else:
logger.debug("Database and tables created successfully")
def get_session(): def get_session():

View file

@ -66,17 +66,24 @@ def extract_input_variables_from_prompt(prompt: str) -> list[str]:
def setup_llm_caching(): def setup_llm_caching():
"""Setup LLM caching.""" """Setup LLM caching."""
from langflow.settings import settings
try: try:
import langchain set_langchain_cache(settings)
from langflow.settings import settings
from langflow.interface.importing.utils import import_class
cache_class = import_class(f"langchain.cache.{settings.cache}")
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
langchain.llm_cache = cache_class()
logger.info(f"LLM caching setup with {cache_class.__name__}")
except ImportError: except ImportError:
logger.warning(f"Could not import {settings.cache}. ") logger.warning(f"Could not import {settings.cache}. ")
except Exception as exc: except Exception as exc:
logger.warning(f"Could not setup LLM caching. Error: {exc}") logger.warning(f"Could not setup LLM caching. Error: {exc}")
# TODO Rename this here and in `setup_llm_caching`
def set_langchain_cache(settings):
import langchain
from langflow.interface.importing.utils import import_class
cache_type = os.getenv("LANGFLOW_LANGCHAIN_CACHE")
cache_class = import_class(f"langchain.cache.{cache_type or settings.cache}")
logger.debug(f"Setting up LLM caching with {cache_class.__name__}")
langchain.llm_cache = cache_class()
logger.info(f"LLM caching setup with {cache_class.__name__}")

View file

@ -1,16 +1,7 @@
# This file is used by lc-serve to load the mounted app and serve it. # This file is used by lc-serve to load the mounted app and serve it.
from pathlib import Path from langflow.main import setup_app
from langflow.utils.logger import configure
from fastapi.staticfiles import StaticFiles configure(log_level="DEBUG")
app = setup_app()
from langflow.main import create_app
app = create_app()
path = Path(__file__).parent
static_files_dir = path / "frontend"
app.mount(
"/",
StaticFiles(directory=static_files_dir, html=True),
name="static",
)

View file

@ -61,7 +61,7 @@ def setup_static_files(app: FastAPI, static_files_dir: Path):
# app = create_app() # app = create_app()
# setup_static_files(app, static_files_dir) # setup_static_files(app, static_files_dir)
def setup_app(static_files_dir: Optional[Path]) -> FastAPI: def setup_app(static_files_dir: Optional[Path] = None) -> FastAPI:
"""Setup the FastAPI app.""" """Setup the FastAPI app."""
# get the directory of the current file # get the directory of the current file
if not static_files_dir: if not static_files_dir:

View file

@ -1,4 +1,5 @@
import os import os
from typing import Optional
import yaml import yaml
from pydantic import BaseSettings, root_validator from pydantic import BaseSettings, root_validator
@ -21,16 +22,18 @@ class Settings(BaseSettings):
textsplitters: dict = {} textsplitters: dict = {}
utilities: dict = {} utilities: dict = {}
dev: bool = False dev: bool = False
database_url: str database_url: Optional[str] = None
cache: str = "InMemoryCache" cache: str = "InMemoryCache"
remove_api_keys: bool = False remove_api_keys: bool = False
@root_validator(pre=True) @root_validator(pre=True)
def set_database_url(cls, values): def set_database_url(cls, values):
if "database_url" not in values: if "database_url" not in values:
logger.debug("No database_url provided, trying DATABASE_URL env variable") logger.debug(
if database_url := os.getenv("DATABASE_URL"): "No database_url provided, trying LANGFLOW_DATABASE_URL env variable"
values["database_url"] = database_url )
if langflow_database_url := os.getenv("LANGFLOW_DATABASE_URL"):
values["database_url"] = langflow_database_url
else: else:
logger.debug("No DATABASE_URL env variable, using sqlite database") logger.debug("No DATABASE_URL env variable, using sqlite database")
values["database_url"] = "sqlite:///./langflow.db" values["database_url"] = "sqlite:///./langflow.db"
@ -39,7 +42,6 @@ class Settings(BaseSettings):
class Config: class Config:
validate_assignment = True validate_assignment = True
extra = "ignore" extra = "ignore"
env_prefix = "LANGFLOW_"
@root_validator(allow_reuse=True) @root_validator(allow_reuse=True)
def validate_lists(cls, values): def validate_lists(cls, values):

View file

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<title>LangFlow</title> <title>Langflow</title>
</head> </head>
<body id='body' style="width: 100%; height:100%"> <body id='body' style="width: 100%; height:100%">
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>

View file

@ -118,7 +118,7 @@ export default function App() {
const removeAlert = (id: string) => { const removeAlert = (id: string) => {
setAlertsList((prevAlertsList) => setAlertsList((prevAlertsList) =>
prevAlertsList.filter((alert) => alert.id !== id) prevAlertsList.filter((alert) => alert.id !== id),
); );
}; };

View file

@ -18,7 +18,7 @@ export default function AccordionComponent({
open = [], open = [],
}: AccordionComponentType) { }: AccordionComponentType) {
const [value, setValue] = useState( const [value, setValue] = useState(
open.length == 0 ? "" : getOpenAccordion() open.length == 0 ? "" : getOpenAccordion(),
); );
function getOpenAccordion() { function getOpenAccordion() {

View file

@ -1,5 +1,5 @@
import { Disclosure } from "@headlessui/react"; import { Disclosure } from "@headlessui/react";
import { useContext, useState } from "react"; import { useContext } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { locationContext } from "../../contexts/locationContext"; import { locationContext } from "../../contexts/locationContext";

View file

@ -127,7 +127,7 @@ export default function BuildTrigger({
async function enforceMinimumLoadingTime( async function enforceMinimumLoadingTime(
startTime: number, startTime: number,
minimumLoadingTime: number minimumLoadingTime: number,
) { ) {
const elapsedTime = Date.now() - startTime; const elapsedTime = Date.now() - startTime;
const remainingTime = minimumLoadingTime - elapsedTime; const remainingTime = minimumLoadingTime - elapsedTime;
@ -156,7 +156,11 @@ export default function BuildTrigger({
leaveFrom="translate-y-0" leaveFrom="translate-y-0"
leaveTo="translate-y-96" leaveTo="translate-y-96"
> >
<div className={'round-buttons-position' + (isBuilt ? " bottom-20" : " bottom-4")}> <div
className={
"round-buttons-position" + (isBuilt ? " bottom-20" : " bottom-4")
}
>
<div <div
className={`${eventClick} round-button-form`} className={`${eventClick} round-button-form`}
onClick={() => { onClick={() => {
@ -175,7 +179,10 @@ export default function BuildTrigger({
value={progress} value={progress}
></RadialProgressComponent> ></RadialProgressComponent>
) : isBuilding ? ( ) : isBuilding ? (
<Loading strokeWidth={1.5} className="build-trigger-loading-icon" /> <Loading
strokeWidth={1.5}
className="build-trigger-loading-icon"
/>
) : ( ) : (
<Zap strokeWidth={1.5} className="build-trigger-icon" /> <Zap strokeWidth={1.5} className="build-trigger-icon" />
)} )}

View file

@ -31,10 +31,7 @@ export default function ChatTrigger({ open, setOpen, isBuilt }) {
leaveTo="translate-y-96" leaveTo="translate-y-96"
> >
<div className="message-button-position"> <div className="message-button-position">
<div <div className="round-button-form" onClick={handleClick}>
className="round-button-form"
onClick={handleClick}
>
<button> <button>
<div className="round-button-div"> <div className="round-button-div">
<MessagesSquare <MessagesSquare

View file

@ -45,7 +45,7 @@ export default function Chat({ flow }: ChatType) {
useEffect(() => { useEffect(() => {
const prevNodes = prevNodesRef.current; const prevNodes = prevNodesRef.current;
const currentNodes = nodes.map( const currentNodes = nodes.map(
(node: NodeType) => node.data.node.template.value (node: NodeType) => node.data.node.template.value,
); );
if ( if (

View file

@ -13,7 +13,7 @@ export default function CodeAreaComponent({
editNode = false, editNode = false,
}: TextAreaComponentType) { }: TextAreaComponentType) {
const [myValue, setMyValue] = useState( const [myValue, setMyValue] = useState(
typeof value == "string" ? value : JSON.stringify(value) typeof value == "string" ? value : JSON.stringify(value),
); );
const { openPopUp } = useContext(PopUpContext); const { openPopUp } = useContext(PopUpContext);
useEffect(() => { useEffect(() => {
@ -43,13 +43,14 @@ export default function CodeAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
className={ className={
editNode editNode
? "input-edit-node input-dialog" ? "input-edit-node input-dialog"
: "input-primary input-dialog " + (disabled ? "input-disable" : "") : "input-dialog input-primary " +
(disabled ? "input-disable" : "")
} }
> >
{myValue !== "" ? myValue : "Type something..."} {myValue !== "" ? myValue : "Type something..."}
@ -63,7 +64,7 @@ export default function CodeAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
> >

View file

@ -4,7 +4,6 @@ import { DropDownComponentType } from "../../types/components";
import { classNames } from "../../utils"; import { classNames } from "../../utils";
import { ChevronsUpDown, Check } from "lucide-react"; import { ChevronsUpDown, Check } from "lucide-react";
import { PopUpContext } from "../../contexts/popUpContext"; import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
export default function Dropdown({ export default function Dropdown({
value, value,

View file

@ -1,4 +1,4 @@
import { BellIcon, Home, MoonIcon, SunIcon, Users2 } from "lucide-react"; import { Home, MoonIcon, SunIcon, Users2 } from "lucide-react";
import { useContext, useEffect, useState } from "react"; import { useContext, useEffect, useState } from "react";
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa"; import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
import { Button } from "../ui/button"; import { Button } from "../ui/button";

View file

@ -110,7 +110,10 @@ export default function InputFileComponent({
</span> </span>
<button onClick={handleButtonClick}> <button onClick={handleButtonClick}>
{!editNode && !loading && ( {!editNode && !loading && (
<FileSearch2 strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground" /> <FileSearch2
strokeWidth={1.5}
className="h-6 w-6 hover:text-accent-foreground"
/>
)} )}
{!editNode && loading && ( {!editNode && loading && (
<span className="loading loading-spinner loading-sm pointer-events-none h-8 pl-3"></span> <span className="loading loading-spinner loading-sm pointer-events-none h-8 pl-3"></span>

View file

@ -31,7 +31,7 @@ export default function PromptAreaComponent({
disabled ? "pointer-events-none w-full cursor-not-allowed" : " w-full" disabled ? "pointer-events-none w-full cursor-not-allowed" : " w-full"
} }
> >
<div className="w-full flex items-center"> <div className="flex w-full items-center">
<span <span
onClick={() => { onClick={() => {
openPopUp( openPopUp(
@ -44,13 +44,15 @@ export default function PromptAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
className={ className={
editNode editNode
? " input-edit-node " + " input-dialog " ? " input-edit-node " + " input-dialog "
: (disabled ? " input-disable " : "") + " input-primary " + " input-dialog " : (disabled ? " input-disable " : "") +
" input-primary " +
" input-dialog "
} }
> >
{myValue !== "" ? myValue : "Type your prompt here"} {myValue !== "" ? myValue : "Type your prompt here"}
@ -67,11 +69,16 @@ export default function PromptAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
> >
{!editNode && <ExternalLink strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground ml-3" />} {!editNode && (
<ExternalLink
strokeWidth={1.5}
className="ml-3 h-6 w-6 hover:text-accent-foreground"
/>
)}
</button> </button>
</div> </div>
</div> </div>

View file

@ -30,9 +30,7 @@ export default function TextAreaComponent({
<div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}> <div className={disabled ? "pointer-events-none cursor-not-allowed" : ""}>
<div <div
className={ className={
editNode editNode ? "w-full items-center" : "flex w-full items-center gap-3"
? "w-full items-center"
: "w-full flex items-center gap-3"
} }
> >
<span <span
@ -47,13 +45,15 @@ export default function TextAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
className={ className={
editNode editNode
? "input-edit-node " + " input-dialog " ? "input-edit-node " + " input-dialog "
: " input_dialog " + "px-3 py-2" + (disabled ? " input-disable " : "") : " input_dialog " +
"px-3 py-2" +
(disabled ? " input-disable " : "")
} }
> >
{myValue !== "" ? myValue : "Type something..."} {myValue !== "" ? myValue : "Type something..."}
@ -70,11 +70,16 @@ export default function TextAreaComponent({
setMyValue(t); setMyValue(t);
onChange(t); onChange(t);
}} }}
/> />,
); );
}} }}
> >
{!editNode && <ExternalLink strokeWidth={1.5} className="w-6 h-6 hover:text-accent-foreground ml-3" />} {!editNode && (
<ExternalLink
strokeWidth={1.5}
className="ml-3 h-6 w-6 hover:text-accent-foreground"
/>
)}
</button> </button>
</div> </div>
</div> </div>

View file

@ -28,7 +28,7 @@ const AccordionTrigger = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180", "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline [&[data-state=open]>svg]:rotate-180",
className className,
)} )}
{...props} {...props}
> >
@ -47,7 +47,7 @@ const AccordionContent = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down", "overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down",
className className,
)} )}
{...props} {...props}
> >

View file

@ -19,7 +19,7 @@ const badgeVariants = cva(
defaultVariants: { defaultVariants: {
variant: "default", variant: "default",
}, },
} },
); );
export interface BadgeProps export interface BadgeProps

View file

@ -30,7 +30,7 @@ const buttonVariants = cva(
variant: "default", variant: "default",
size: "default", size: "default",
}, },
} },
); );
export interface ButtonProps export interface ButtonProps
@ -49,7 +49,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
{...props} {...props}
/> />
); );
} },
); );
Button.displayName = "Button"; Button.displayName = "Button";

View file

@ -13,7 +13,7 @@ const Checkbox = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
className className,
)} )}
{...props} {...props}
> >

View file

@ -44,7 +44,7 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content <DialogPrimitive.Content
ref={ref} ref={ref}
className={cn( className={cn(
"fixed gap-3 z-50 grid w-full rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0", "fixed z-50 grid w-full gap-3 rounded-b-lg border bg-background p-6 shadow-lg animate-in data-[state=open]:fade-in-90 data-[state=open]:slide-in-from-bottom-10 sm:max-w-lg sm:rounded-lg sm:zoom-in-90 data-[state=open]:sm:slide-in-from-bottom-0",
className className
)} )}
{...props} {...props}

View file

@ -28,7 +28,7 @@ const DropdownMenuSubTrigger = React.forwardRef<
className={cn( className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent", "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent data-[state=open]:bg-accent",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
> >
@ -47,7 +47,7 @@ const DropdownMenuSubContent = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
className className,
)} )}
{...props} {...props}
/> />
@ -65,7 +65,7 @@ const DropdownMenuContent = React.forwardRef<
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className className,
)} )}
{...props} {...props}
/> />
@ -84,7 +84,7 @@ const DropdownMenuItem = React.forwardRef<
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
/> />
@ -99,7 +99,7 @@ const DropdownMenuCheckboxItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className,
)} )}
checked={checked} checked={checked}
{...props} {...props}
@ -123,7 +123,7 @@ const DropdownMenuRadioItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none transition-colors focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className,
)} )}
{...props} {...props}
> >
@ -148,7 +148,7 @@ const DropdownMenuLabel = React.forwardRef<
className={cn( className={cn(
"px-2 py-1.5 pl-2 text-sm font-semibold", "px-2 py-1.5 pl-2 text-sm font-semibold",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
/> />

View file

@ -11,13 +11,13 @@ const Input = React.forwardRef<HTMLInputElement, InputProps>(
type={type} type={type}
className={cn( className={cn(
"flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "flex h-10 w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className className,
)} )}
ref={ref} ref={ref}
{...props} {...props}
/> />
); );
} },
); );
Input.displayName = "Input"; Input.displayName = "Input";

View file

@ -6,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "../../utils"; import { cn } from "../../utils";
const labelVariants = cva( const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70" "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
); );
const Label = React.forwardRef< const Label = React.forwardRef<

View file

@ -24,7 +24,7 @@ const Menubar = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"flex h-10 items-center space-x-1 rounded-md border bg-background p-1", "flex h-10 items-center space-x-1 rounded-md border bg-background p-1",
className className,
)} )}
{...props} {...props}
/> />
@ -39,7 +39,7 @@ const MenubarTrigger = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", "flex cursor-default select-none items-center rounded-sm px-3 py-1.5 text-sm font-medium outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
className className,
)} )}
{...props} {...props}
/> />
@ -57,7 +57,7 @@ const MenubarSubTrigger = React.forwardRef<
className={cn( className={cn(
"flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground", "flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[state=open]:bg-accent data-[state=open]:text-accent-foreground",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
> >
@ -75,7 +75,7 @@ const MenubarSubContent = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", "z-50 min-w-[8rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
className className,
)} )}
{...props} {...props}
/> />
@ -88,7 +88,7 @@ const MenubarContent = React.forwardRef<
>( >(
( (
{ className, align = "start", alignOffset = -4, sideOffset = 8, ...props }, { className, align = "start", alignOffset = -4, sideOffset = 8, ...props },
ref ref,
) => ( ) => (
<MenubarPrimitive.Portal> <MenubarPrimitive.Portal>
<MenubarPrimitive.Content <MenubarPrimitive.Content
@ -98,12 +98,12 @@ const MenubarContent = React.forwardRef<
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in slide-in-from-top-1", "z-50 min-w-[12rem] overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md animate-in slide-in-from-top-1",
className className,
)} )}
{...props} {...props}
/> />
</MenubarPrimitive.Portal> </MenubarPrimitive.Portal>
) ),
); );
MenubarContent.displayName = MenubarPrimitive.Content.displayName; MenubarContent.displayName = MenubarPrimitive.Content.displayName;
@ -118,7 +118,7 @@ const MenubarItem = React.forwardRef<
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
/> />
@ -133,7 +133,7 @@ const MenubarCheckboxItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className,
)} )}
checked={checked} checked={checked}
{...props} {...props}
@ -156,7 +156,7 @@ const MenubarRadioItem = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "relative flex cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className,
)} )}
{...props} {...props}
> >
@ -181,7 +181,7 @@ const MenubarLabel = React.forwardRef<
className={cn( className={cn(
"px-2 py-1.5 text-sm font-semibold", "px-2 py-1.5 text-sm font-semibold",
inset && "pl-8", inset && "pl-8",
className className,
)} )}
{...props} {...props}
/> />
@ -208,7 +208,7 @@ const MenubarShortcut = ({
<span <span
className={cn( className={cn(
"ml-auto text-xs tracking-widest text-muted-foreground", "ml-auto text-xs tracking-widest text-muted-foreground",
className className,
)} )}
{...props} {...props}
/> />

View file

@ -12,7 +12,7 @@ const Progress = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"relative h-4 w-full overflow-hidden rounded-full bg-secondary", "relative h-4 w-full overflow-hidden rounded-full bg-secondary",
className className,
)} )}
{...props} {...props}
> >

View file

@ -10,7 +10,7 @@ const Separator = React.forwardRef<
>( >(
( (
{ className, orientation = "horizontal", decorative = true, ...props }, { className, orientation = "horizontal", decorative = true, ...props },
ref ref,
) => ( ) => (
<SeparatorPrimitive.Root <SeparatorPrimitive.Root
ref={ref} ref={ref}
@ -19,11 +19,11 @@ const Separator = React.forwardRef<
className={cn( className={cn(
"shrink-0 bg-border", "shrink-0 bg-border",
orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]", orientation === "horizontal" ? "h-[1px] w-full" : "h-full w-[1px]",
className className,
)} )}
{...props} {...props}
/> />
) ),
); );
Separator.displayName = SeparatorPrimitive.Root.displayName; Separator.displayName = SeparatorPrimitive.Root.displayName;

View file

@ -55,7 +55,7 @@ const TableRow = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
className className,
)} )}
{...props} {...props}
/> />
@ -70,7 +70,7 @@ const TableHead = React.forwardRef<
ref={ref} ref={ref}
className={cn( className={cn(
"h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0", "h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",
className className,
)} )}
{...props} {...props}
/> />

View file

@ -10,13 +10,13 @@ const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
<textarea <textarea
className={cn( className={cn(
"flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", "flex min-h-[80px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className className,
)} )}
ref={ref} ref={ref}
{...props} {...props}
/> />
); );
} },
); );
Textarea.displayName = "Textarea"; Textarea.displayName = "Textarea";

View file

@ -19,7 +19,7 @@ const TooltipContent = React.forwardRef<
sideOffset={sideOffset} sideOffset={sideOffset}
className={cn( className={cn(
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", "z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
className className,
)} )}
{...props} {...props}
/> />

View file

@ -134,7 +134,7 @@ TWEAKS = ${
} }
flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS) flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS)
# Now you can use it like any chain # Now you can use it like any chain
flow("Hey, have you heard of LangFlow?")`; flow("Hey, have you heard of Langflow?")`;
}; };
function buildTweakObject(tweak) { function buildTweakObject(tweak) {

View file

@ -132,7 +132,7 @@ export function AlertProvider({ children }: { children: ReactNode }) {
function removeFromNotificationList(index: string) { function removeFromNotificationList(index: string) {
// set the notification list to a new array that filters out the alert with the matching id // set the notification list to a new array that filters out the alert with the matching id
setNotificationList((prevAlertsList) => setNotificationList((prevAlertsList) =>
prevAlertsList.filter((alert) => alert.id !== index) prevAlertsList.filter((alert) => alert.id !== index),
); );
} }
return ( return (

View file

@ -14,7 +14,7 @@ export const darkContext = createContext<darkContextType>(initialValue);
export function DarkProvider({ children }) { export function DarkProvider({ children }) {
const [dark, setDark] = useState( const [dark, setDark] = useState(
JSON.parse(window.localStorage.getItem("isDark")) ?? false JSON.parse(window.localStorage.getItem("isDark")) ?? false,
); );
useEffect(() => { useEffect(() => {
if (dark) { if (dark) {

View file

@ -53,7 +53,7 @@ export const locationContext = createContext<locationContextType>(initialValue);
export function LocationProvider({ children }: { children: ReactNode }) { export function LocationProvider({ children }: { children: ReactNode }) {
const [current, setCurrent] = useState(initialValue.current); const [current, setCurrent] = useState(initialValue.current);
const [isStackedOpen, setIsStackedOpen] = useState( const [isStackedOpen, setIsStackedOpen] = useState(
initialValue.isStackedOpen initialValue.isStackedOpen,
); );
const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar); const [showSideBar, setShowSideBar] = useState(initialValue.showSideBar);
const [extraNavigation, setExtraNavigation] = useState({ title: "" }); const [extraNavigation, setExtraNavigation] = useState({ title: "" });

View file

@ -111,7 +111,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
// function loadCookie(cookie: string) { // function loadCookie(cookie: string) {
// if (cookie && Object.keys(templates).length > 0) { // if (cookie && Object.keys(templates).length > 0) {
// let cookieObject: LangFlowState = JSON.parse(cookie); // let cookieObject: LangflowState = JSON.parse(cookie);
// try { // try {
// cookieObject.flows.forEach((flow) => { // cookieObject.flows.forEach((flow) => {
// if (!flow.data) { // if (!flow.data) {
@ -288,7 +288,11 @@ export function TabsProvider({ children }: { children: ReactNode }) {
// create a link element and set its properties // create a link element and set its properties
const link = document.createElement("a"); const link = document.createElement("a");
link.href = jsonString; link.href = jsonString;
link.download = `${flowName && flowName != "" ? flowName : flows.find((f) => f.id === tabId).name}.json`; link.download = `${
flowName && flowName != ""
? flowName
: flows.find((f) => f.id === tabId).name
}.json`;
// simulate a click on the link element to trigger the download // simulate a click on the link element to trigger the download
link.click(); link.click();

View file

@ -47,7 +47,7 @@ export function TypesProvider({ children }: { children: ReactNode }) {
acc[c] = result.data[curr][c]; acc[c] = result.data[curr][c];
}); });
return acc; return acc;
}, {}) }, {}),
); );
// Set the types by reducing over the keys of the result data and updating the accumulator. // Set the types by reducing over the keys of the result data and updating the accumulator.
setTypes( setTypes(
@ -62,10 +62,10 @@ export function TypesProvider({ children }: { children: ReactNode }) {
result.data[curr][c].base_classes?.forEach((b) => { result.data[curr][c].base_classes?.forEach((b) => {
acc[b] = curr; acc[b] = curr;
}); });
} },
); );
return acc; return acc;
}, {}) }, {}),
); );
} }
// Clear the interval if successful. // Clear the interval if successful.
@ -99,12 +99,12 @@ export function TypesProvider({ children }: { children: ReactNode }) {
function deleteNode(idx: string) { function deleteNode(idx: string) {
reactFlowInstance.setNodes( reactFlowInstance.setNodes(
reactFlowInstance.getNodes().filter((n: Node) => n.id !== idx) reactFlowInstance.getNodes().filter((n: Node) => n.id !== idx),
); );
reactFlowInstance.setEdges( reactFlowInstance.setEdges(
reactFlowInstance reactFlowInstance
.getEdges() .getEdges()
.filter((ns) => ns.source !== idx && ns.target !== idx) .filter((ns) => ns.source !== idx && ns.target !== idx),
); );
} }
return ( return (

View file

@ -52,7 +52,7 @@ export function UndoRedoProvider({ children }) {
const [past, setPast] = useState<HistoryItem[][]>(flows.map(() => [])); const [past, setPast] = useState<HistoryItem[][]>(flows.map(() => []));
const [future, setFuture] = useState<HistoryItem[][]>(flows.map(() => [])); const [future, setFuture] = useState<HistoryItem[][]>(flows.map(() => []));
const [tabIndex, setTabIndex] = useState( const [tabIndex, setTabIndex] = useState(
flows.findIndex((f) => f.id === tabId) flows.findIndex((f) => f.id === tabId),
); );
useEffect(() => { useEffect(() => {
@ -70,7 +70,7 @@ export function UndoRedoProvider({ children }) {
let newPast = cloneDeep(old); let newPast = cloneDeep(old);
newPast[tabIndex] = old[tabIndex].slice( newPast[tabIndex] = old[tabIndex].slice(
old[tabIndex].length - defaultOptions.maxHistorySize + 1, old[tabIndex].length - defaultOptions.maxHistorySize + 1,
old[tabIndex].length old[tabIndex].length,
); );
newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() }); newPast[tabIndex].push({ nodes: getNodes(), edges: getEdges() });
return newPast; return newPast;

View file

@ -24,7 +24,7 @@ const GITHUB_API_URL = "https://api.github.com";
export async function getRepoStars(owner, repo) { export async function getRepoStars(owner, repo) {
try { try {
const response = await axios.get( const response = await axios.get(
`${GITHUB_API_URL}/repos/${owner}/${repo}` `${GITHUB_API_URL}/repos/${owner}/${repo}`,
); );
return response.data.stargazers_count; return response.data.stargazers_count;
} catch (error) { } catch (error) {
@ -44,7 +44,7 @@ export async function sendAll(data: sendAllProps) {
} }
export async function postValidateCode( export async function postValidateCode(
code: string code: string,
): Promise<AxiosResponse<errorsTypeAPI>> { ): Promise<AxiosResponse<errorsTypeAPI>> {
return await axios.post("/api/v1/validate/code", { code }); return await axios.post("/api/v1/validate/code", { code });
} }
@ -56,7 +56,7 @@ export async function postValidateCode(
* @returns {Promise<AxiosResponse<PromptTypeAPI>>} A promise that resolves to an AxiosResponse containing the validation results. * @returns {Promise<AxiosResponse<PromptTypeAPI>>} A promise that resolves to an AxiosResponse containing the validation results.
*/ */
export async function checkPrompt( export async function checkPrompt(
template: string template: string,
): Promise<AxiosResponse<PromptTypeAPI>> { ): Promise<AxiosResponse<PromptTypeAPI>> {
return await axios.post("/api/v1/validate/prompt", { template }); return await axios.post("/api/v1/validate/prompt", { template });
} }
@ -120,7 +120,7 @@ export async function saveFlowToDatabase(newFlow: {
* @throws Will throw an error if the update fails. * @throws Will throw an error if the update fails.
*/ */
export async function updateFlowInDatabase( export async function updateFlowInDatabase(
updatedFlow: FlowType updatedFlow: FlowType,
): Promise<FlowType> { ): Promise<FlowType> {
try { try {
const response = await axios.patch(`/api/v1/flows/${updatedFlow.id}`, { const response = await axios.patch(`/api/v1/flows/${updatedFlow.id}`, {
@ -296,7 +296,7 @@ export async function getHealth() {
* *
*/ */
export async function getBuildStatus( export async function getBuildStatus(
flowId: string flowId: string,
): Promise<BuildStatusTypeAPI> { ): Promise<BuildStatusTypeAPI> {
return await axios.get(`/api/v1/build/${flowId}/status`); return await axios.get(`/api/v1/build/${flowId}/status`);
} }
@ -309,7 +309,7 @@ export async function getBuildStatus(
* *
*/ */
export async function postBuildInit( export async function postBuildInit(
flow: FlowType flow: FlowType,
): Promise<AxiosResponse<InitTypeAPI>> { ): Promise<AxiosResponse<InitTypeAPI>> {
return await axios.post(`/api/v1/build/init/${flow.id}`, flow); return await axios.post(`/api/v1/build/init/${flow.id}`, flow);
} }
@ -325,7 +325,7 @@ export async function postBuildInit(
*/ */
export async function uploadFile( export async function uploadFile(
file: File, file: File,
id: string id: string,
): Promise<AxiosResponse<UploadFileTypeAPI>> { ): Promise<AxiosResponse<UploadFileTypeAPI>> {
const formData = new FormData(); const formData = new FormData();
formData.append("file", file); formData.append("file", file);

View file

@ -20,7 +20,7 @@ export const DESCRIPTIONS: string[] = [
"Generate, Innovate, Communicate.", "Generate, Innovate, Communicate.",
"Conversation Catalyst Engine.", "Conversation Catalyst Engine.",
"Language Chainlink Master.", "Language Chainlink Master.",
"Design Dialogues with LangFlow.", "Design Dialogues with Langflow.",
"Nurture NLP Nodes Here.", "Nurture NLP Nodes Here.",
"Conversational Cartography Unlocked.", "Conversational Cartography Unlocked.",
"Design, Develop, Dialogize.", "Design, Develop, Dialogize.",
@ -31,7 +31,7 @@ export const DESCRIPTIONS: string[] = [
"Where Language Meets Logic.", "Where Language Meets Logic.",
"Building Intelligent Interactions.", "Building Intelligent Interactions.",
"Your Passport to Linguistic Landscapes.", "Your Passport to Linguistic Landscapes.",
"Create, Curate, Communicate with LangFlow.", "Create, Curate, Communicate with Langflow.",
"Flow into the Future of Language.", "Flow into the Future of Language.",
"Mapping Meaningful Conversations.", "Mapping Meaningful Conversations.",
"Unravel the Art of Articulation.", "Unravel the Art of Articulation.",
@ -41,7 +41,7 @@ export const DESCRIPTIONS: string[] = [
"The Pinnacle of Prompt Generation.", "The Pinnacle of Prompt Generation.",
"Language Models, Mapped and Mastered.", "Language Models, Mapped and Mastered.",
"Powerful Prompts, Perfectly Positioned.", "Powerful Prompts, Perfectly Positioned.",
"Innovation in Interaction with LangFlow.", "Innovation in Interaction with Langflow.",
"Your Toolkit for Text Generation.", "Your Toolkit for Text Generation.",
"Unfolding Linguistic Possibilities.", "Unfolding Linguistic Possibilities.",
"Building Powerful Solutions with Language Models.", "Building Powerful Solutions with Language Models.",

View file

@ -4,5 +4,5 @@ import { ReactComponent as AzSVG } from "./az_logo.svg";
export const AzIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const AzIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <AzSVG ref={ref} {...props} />; return <AzSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as BingSVG } from "./bing.svg";
export const BingIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const BingIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <BingSVG ref={ref} {...props} />; return <BingSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as FacebookMessengerSVG } from "./Facebook_Messenger_log
export const FBIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const FBIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <FacebookMessengerSVG ref={ref} {...props} />; return <FacebookMessengerSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as IFixItSVG } from "./ifixit-seeklogo.com.svg";
export const IFixIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const IFixIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <IFixItSVG ref={ref} {...props} />; return <IFixItSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as MetaSVG } from "./meta-icon.svg";
export const MetaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const MetaIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <MetaSVG ref={ref} {...props} />; return <MetaSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as SearxSVG } from "./Searx_logo.svg";
export const SearxIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const SearxIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <SearxSVG ref={ref} {...props} />; return <SearxSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as SlackSVG } from "./slack-icon.svg";
export const SlackIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const SlackIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <SlackSVG ref={ref} {...props} />; return <SlackSVG ref={ref} {...props} />;
} },
); );

View file

@ -4,5 +4,5 @@ import { ReactComponent as WordSVG } from "./word.svg";
export const WordIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>( export const WordIcon = forwardRef<SVGSVGElement, React.PropsWithChildren<{}>>(
(props, ref) => { (props, ref) => {
return <WordSVG ref={ref} {...props} />; return <WordSVG ref={ref} {...props} />;
} },
); );

View file

@ -482,10 +482,10 @@ The cursor: default; property value restores the browser's default cursor style
} }
.dropdown-component-outline { .dropdown-component-outline {
@apply relative pr-8 input-edit-node @apply border-1 input-edit-node relative pr-8
} }
.dropdown-component-false-outline { .dropdown-component-false-outline {
@apply py-2 pl-3 pr-10 text-left input-primary @apply input-primary py-2 pl-3 pr-10 text-left
} }
.dropdown-component-display { .dropdown-component-display {
@apply block w-full truncate bg-background @apply block w-full truncate bg-background
@ -558,7 +558,7 @@ The cursor: default; property value restores the browser's default cursor style
@apply ml-auto mr-2 flex items-center gap-5 @apply ml-auto mr-2 flex items-center gap-5
} }
.header-github-link { .header-github-link {
@apply inline-flex shadow-sm items-center justify-center text-sm font-medium focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background text-muted-foreground border border-input hover:bg-accent hover:text-accent-foreground h-9 px-3 pr-0 rounded-md @apply inline-flex h-9 items-center justify-center rounded-md border border-input px-3 pr-0 text-sm font-medium text-muted-foreground shadow-sm ring-offset-background hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50
} }
.header-github-display { .header-github-display {
@apply -mr-px ml-2 flex h-9 items-center justify-center rounded-md rounded-l-none border bg-background px-2 text-sm @apply -mr-px ml-2 flex h-9 items-center justify-center rounded-md rounded-l-none border bg-background px-2 text-sm

View file

@ -8,13 +8,13 @@ import ContextWrapper from "./contexts";
import "./index.css"; import "./index.css";
const root = ReactDOM.createRoot( const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement document.getElementById("root") as HTMLElement,
); );
root.render( root.render(
<ContextWrapper> <ContextWrapper>
<BrowserRouter> <BrowserRouter>
<App /> <App />
</BrowserRouter> </BrowserRouter>
</ContextWrapper> </ContextWrapper>,
); );
reportWebVitals(); reportWebVitals();

View file

@ -104,11 +104,10 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
useEffect(() => { useEffect(() => {
if (closeEdit !== "") { if (closeEdit !== "") {
tweak.current = getTweak; tweak.current = getTweak;
if(tweak.current.length > 0){ if (tweak.current.length > 0) {
setActiveTab("3"); setActiveTab("3");
openAccordions(); openAccordions();
} } else {
else{
startTweaks(); startTweaks();
} }
} else { } else {
@ -157,7 +156,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n].type === "code" || t.data.node.template[n].type === "code" ||
t.data.node.template[n].type === "prompt" || t.data.node.template[n].type === "prompt" ||
t.data.node.template[n].type === "file" || t.data.node.template[n].type === "file" ||
t.data.node.template[n].type === "int") t.data.node.template[n].type === "int"),
) )
.map((n, i) => { .map((n, i) => {
arrNodesWithValues.push(t["id"]); arrNodesWithValues.push(t["id"]);
@ -181,7 +180,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
} }
const existingTweak = tweak.current.find((element) => const existingTweak = tweak.current.find((element) =>
element.hasOwnProperty(tw) element.hasOwnProperty(tw),
); );
if (existingTweak) { if (existingTweak) {
@ -250,25 +249,25 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
function openAccordions() { function openAccordions() {
let accordionsToOpen = []; let accordionsToOpen = [];
tweak.current.forEach((el) => { tweak.current.forEach((el) => {
Object.keys(el).forEach((key) => { Object.keys(el).forEach((key) => {
if (Object.keys(el[key]).length > 0) { if (Object.keys(el[key]).length > 0) {
accordionsToOpen.push(key); accordionsToOpen.push(key);
setOpenAccordion(accordionsToOpen); setOpenAccordion(accordionsToOpen);
} }
});
}); });
});
} }
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
<DialogTrigger></DialogTrigger> <DialogTrigger></DialogTrigger>
<DialogContent className="lg:max-w-[80vw] h-[80vh]"> <DialogContent className="h-[80vh] lg:max-w-[80vw]">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Code</span> <span className="pr-2">Code</span>
<Code2 <Code2
className="h-6 w-6 text-gray-800 pl-1 dark:text-white" className="h-6 w-6 pl-1 text-gray-800 dark:text-white"
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </DialogTitle>
@ -277,7 +276,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
<Tabs <Tabs
value={activeTab} value={activeTab}
className="w-full h-full overflow-hidden text-center bg-muted rounded-md border" className="h-full w-full overflow-hidden rounded-md border bg-muted text-center"
onValueChange={(value) => { onValueChange={(value) => {
setActiveTab(value); setActiveTab(value);
if (value === "3") { if (value === "3") {
@ -296,7 +295,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
{Number(activeTab) < 3 && ( {Number(activeTab) < 3 && (
<div className="float-right"> <div className="float-right">
<button <button
className="flex gap-1.5 items-center rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300" className="flex items-center gap-1.5 rounded bg-none p-1 text-xs text-gray-500 dark:text-gray-300"
onClick={copyToClipboard} onClick={copyToClipboard}
> >
{isCopied ? <Check size={18} /> : <Clipboard size={15} />} {isCopied ? <Check size={18} /> : <Clipboard size={15} />}
@ -309,12 +308,12 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
{tabs.map((tab, index) => ( {tabs.map((tab, index) => (
<TabsContent <TabsContent
value={index.toString()} value={index.toString()}
className="overflow-hidden w-full h-full px-4 pb-4 -mt-1" className="-mt-1 h-full w-full overflow-hidden px-4 pb-4"
key={index} // Remember to add a unique key prop key={index} // Remember to add a unique key prop
> >
{index < 3 ? ( {index < 3 ? (
<SyntaxHighlighter <SyntaxHighlighter
className="w-full overflow-auto h-[60vh]" className="h-[60vh] w-full overflow-auto"
language={tab.mode} language={tab.mode}
style={oneDark} style={oneDark}
> >
@ -322,13 +321,13 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</SyntaxHighlighter> </SyntaxHighlighter>
) : index === 3 ? ( ) : index === 3 ? (
<> <>
<div className="flex w-full h-full mt-2"> <div className="mt-2 flex h-full w-full">
<div <div
className={classNames( className={classNames(
"w-full rounded-lg bg-muted h-[60vh]", "h-[60vh] w-full rounded-lg bg-muted",
1 == 1 1 == 1
? "overflow-scroll overflow-x-hidden custom-scroll" ? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden" : "overflow-hidden",
)} )}
> >
{flow["data"]["nodes"].map((t: any, index) => ( {flow["data"]["nodes"].map((t: any, index) => (
@ -338,14 +337,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
trigger={t["data"]["id"]} trigger={t["data"]["id"]}
open={openAccordion} open={openAccordion}
> >
<div className="flex flex-col gap-5 h-fit"> <div className="flex h-fit flex-col gap-5">
<Table className="table-fixed bg-muted outline-1"> <Table className="table-fixed bg-muted outline-1">
<TableHeader className="border-input text-xs font-medium text-ring h-10"> <TableHeader className="h-10 border-input text-xs font-medium text-ring">
<TableRow className="dark:border-b-muted"> <TableRow className="dark:border-b-muted">
<TableHead className="h-7 text-center"> <TableHead className="h-7 text-center">
PARAM PARAM
</TableHead> </TableHead>
<TableHead className="p-0 h-7 text-center"> <TableHead className="h-7 p-0 text-center">
VALUE VALUE
</TableHead> </TableHead>
</TableRow> </TableRow>
@ -369,7 +368,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n].type === t.data.node.template[n].type ===
"file" || "file" ||
t.data.node.template[n].type === t.data.node.template[n].type ===
"int") "int"),
) )
.map((n, i) => { .map((n, i) => {
//console.log(t.data.node.template[n]); //console.log(t.data.node.template[n]);
@ -379,11 +378,11 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
key={i} key={i}
className="h-10 dark:border-b-muted" className="h-10 dark:border-b-muted"
> >
<TableCell className="p-0 text-center text-gray-900 text-sm"> <TableCell className="p-0 text-center text-sm text-gray-900">
{n} {n}
</TableCell> </TableCell>
<TableCell className="p-0 text-center text-gray-900 text-xs dark:text-gray-300"> <TableCell className="p-0 text-center text-xs text-gray-900 dark:text-gray-300">
<div className="w-[250px] m-auto"> <div className="m-auto w-[250px]">
{t.data.node.template[n] {t.data.node.template[n]
.type === "str" && .type === "str" &&
!t.data.node.template[n] !t.data.node.template[n]
@ -412,7 +411,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t["data"]["id"], t["data"]["id"],
k, k,
t.data.node t.data.node
.template[n] .template[n],
); );
}} }}
/> />
@ -423,7 +422,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
content={buildContent( content={buildContent(
t.data.node.template[ t.data.node.template[
n n
].value ].value,
)} )}
> >
<div> <div>
@ -436,14 +435,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
.value, .value,
t.data, t.data,
t.data.node t.data.node
.template[n] .template[n],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"]["id"],
k, k,
t.data.node t.data.node
.template[n] .template[n],
); );
}} }}
/> />
@ -465,14 +464,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data, t.data,
t.data.node.template[ t.data.node.template[
n n
] ],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"]["id"],
k, k,
t.data.node t.data.node
.template[n] .template[n],
); );
}} }}
/> />
@ -497,7 +496,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
e, e,
t.data.node.template[ t.data.node.template[
n n
] ],
); );
}} }}
size="small" size="small"
@ -513,8 +512,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
) ),
)} )}
> >
<div className="mx-auto"> <div className="mx-auto">
@ -527,7 +526,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
].value ?? "" ].value ?? ""
} }
onChange={( onChange={(
k: any k: any,
) => {}} ) => {}}
fileTypes={ fileTypes={
t.data.node.template[ t.data.node.template[
@ -540,7 +539,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
].suffixes ].suffixes
} }
onFileChange={( onFileChange={(
k: any k: any,
) => {}} ) => {}}
></InputFileComponent> ></InputFileComponent>
</div> </div>
@ -555,7 +554,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
@ -563,7 +562,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
k, k,
t.data.node.template[ t.data.node.template[
n n
] ],
); );
}} }}
/> />
@ -586,14 +585,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
k, k,
t.data.node.template[ t.data.node.template[
n n
] ],
); );
}} }}
value={getValue( value={getValue(
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
)} )}
></Dropdown> ></Dropdown>
</div> </div>
@ -607,7 +606,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
@ -615,7 +614,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
k, k,
t.data.node.template[ t.data.node.template[
n n
] ],
); );
}} }}
/> />
@ -629,8 +628,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
) ),
)} )}
> >
<div className="mx-auto"> <div className="mx-auto">
@ -644,14 +643,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data, t.data,
t.data.node.template[ t.data.node.template[
n n
] ],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"]["id"],
k, k,
t.data.node t.data.node
.template[n] .template[n],
); );
}} }}
/> />
@ -666,8 +665,8 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data.node.template[n] t.data.node.template[n]
.value, .value,
t.data, t.data,
t.data.node.template[n] t.data.node.template[n],
) ),
)} )}
> >
<div className="mx-auto"> <div className="mx-auto">
@ -681,14 +680,14 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
t.data, t.data,
t.data.node.template[ t.data.node.template[
n n
] ],
)} )}
onChange={(k) => { onChange={(k) => {
buildTweakObject( buildTweakObject(
t["data"]["id"], t["data"]["id"],
k, k,
t.data.node t.data.node
.template[n] .template[n],
); );
}} }}
/> />

View file

@ -47,8 +47,8 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node.template[t].type === "code" || data.node.template[t].type === "code" ||
data.node.template[t].type === "prompt" || data.node.template[t].type === "prompt" ||
data.node.template[t].type === "file" || data.node.template[t].type === "file" ||
data.node.template[t].type === "int") data.node.template[t].type === "int"),
).length ).length,
); );
const [nodeValue, setNodeValue] = useState(null); const [nodeValue, setNodeValue] = useState(null);
const { closePopUp } = useContext(PopUpContext); const { closePopUp } = useContext(PopUpContext);
@ -81,7 +81,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
<DialogTrigger asChild></DialogTrigger> <DialogTrigger asChild></DialogTrigger>
<DialogContent className="lg:max-w-[700px] sm:max-w-[600px]"> <DialogContent className="sm:max-w-[600px] lg:max-w-[700px]">
<DialogHeader> <DialogHeader>
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">{data.type}</span> <span className="pr-2">{data.type}</span>
@ -104,7 +104,7 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
"w-full rounded-lg border-[1px] border-input bg-background", "w-full rounded-lg border-[1px] border-input bg-background",
nodeLength > limitScrollFieldsModal nodeLength > limitScrollFieldsModal
? "overflow-scroll overflow-x-hidden custom-scroll" ? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden" : "overflow-hidden",
)} )}
> >
{nodeLength > 0 && ( {nodeLength > 0 && (
@ -131,11 +131,11 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
data.node.template[t].type === "code" || data.node.template[t].type === "code" ||
data.node.template[t].type === "prompt" || data.node.template[t].type === "prompt" ||
data.node.template[t].type === "file" || data.node.template[t].type === "file" ||
data.node.template[t].type === "int") data.node.template[t].type === "int"),
) )
.map((n, i) => ( .map((n, i) => (
<TableRow key={i} className="h-10"> <TableRow key={i} className="h-10">
<TableCell className="p-0 text-center text-sm text-foreground truncate sm:px-3"> <TableCell className="truncate p-0 text-center text-sm text-foreground sm:px-3">
{data.node.template[n].name {data.node.template[n].name
? data.node.template[n].name ? data.node.template[n].name
: data.node.template[n].display_name} : data.node.template[n].display_name}

View file

@ -22,7 +22,7 @@ export default function ModalField({
index, index,
}) { }) {
const [enabled, setEnabled] = useState( const [enabled, setEnabled] = useState(
data.node.template[name]?.value ?? false data.node.template[name]?.value ?? false,
); );
const display = const display =
type === "str" || type === "str" ||
@ -42,12 +42,12 @@ export default function ModalField({
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
data.node.template[t].advanced && data.node.template[t].advanced &&
data.node.template[t].show data.node.template[t].show,
).length - ).length -
1 === 1 ===
index index
? "pb-4" ? "pb-4"
: "" : "",
)} )}
> >
{display && ( {display && (

View file

@ -100,10 +100,10 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
data.node.template[t].advanced && data.node.template[t].advanced &&
data.node.template[t].show data.node.template[t].show,
).length > limitScrollFieldsModal ).length > limitScrollFieldsModal
? "overflow-scroll overflow-x-hidden custom-scroll" ? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden" : "overflow-hidden",
)} )}
> >
<div className="flex h-full flex-col gap-5"> <div className="flex h-full flex-col gap-5">
@ -112,7 +112,7 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
(t) => (t) =>
t.charAt(0) !== "_" && t.charAt(0) !== "_" &&
data.node.template[t].advanced && data.node.template[t].advanced &&
data.node.template[t].show data.node.template[t].show,
) )
.map((t: string, idx) => { .map((t: string, idx) => {
return ( return (

View file

@ -1,6 +1,5 @@
import { classNames } from "../../../utils"; import { classNames } from "../../../utils";
import { useContext, useEffect, useRef, useState } from "react"; import { useEffect } from "react";
import { TabsContext } from "../../../contexts/tabsContext";
import { Lock, Send } from "lucide-react"; import { Lock, Send } from "lucide-react";
export default function ChatInput({ export default function ChatInput({

View file

@ -380,7 +380,7 @@ export default function ChatModal({
<span> <span>
👋{" "} 👋{" "}
<span className="text-lg text-muted-foreground"> <span className="text-lg text-muted-foreground">
LangFlow Chat Langflow Chat
</span> </span>
</span> </span>
<br /> <br />

View file

@ -53,8 +53,8 @@ export default function CodeAreaModal({
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Edit Code</span> <span className="pr-2">Edit Code</span>
<TerminalSquare <TerminalSquare
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 text-primary pl-1 " className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </DialogTitle>
@ -118,7 +118,7 @@ export default function CodeAreaModal({
setErrorData({ setErrorData({
title: title:
"There is something wrong with this code, please review it", "There is something wrong with this code, please review it",
}) }),
); );
}} }}
type="submit" type="submit"

View file

@ -37,7 +37,7 @@ export default function ExportModal() {
const [checked, setChecked] = useState(false); const [checked, setChecked] = useState(false);
const [name, setName] = useState(flows.find((f) => f.id === tabId).name); const [name, setName] = useState(flows.find((f) => f.id === tabId).name);
const [description, setDescription] = useState( const [description, setDescription] = useState(
flows.find((f) => f.id === tabId).description flows.find((f) => f.id === tabId).description,
); );
return ( return (
<Dialog open={true} onOpenChange={setModalOpen}> <Dialog open={true} onOpenChange={setModalOpen}>
@ -47,8 +47,8 @@ export default function ExportModal() {
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">Export</span> <span className="pr-2">Export</span>
<Download <Download
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 text-foreground pl-1" className="h-6 w-6 pl-1 text-foreground"
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </DialogTitle>

View file

@ -27,7 +27,7 @@ export default function FlowSettingsModal() {
const maxLength = 50; const maxLength = 50;
const [name, setName] = useState(flows.find((f) => f.id === tabId).name); const [name, setName] = useState(flows.find((f) => f.id === tabId).name);
const [description, setDescription] = useState( const [description, setDescription] = useState(
flows.find((f) => f.id === tabId).description flows.find((f) => f.id === tabId).description,
); );
function setModalOpen(x: boolean) { function setModalOpen(x: boolean) {
setOpen(x); setOpen(x);

View file

@ -56,8 +56,8 @@ export default function GenericModal({
<DialogTitle className="flex items-center"> <DialogTitle className="flex items-center">
<span className="pr-2">{myModalTitle}</span> <span className="pr-2">{myModalTitle}</span>
<FileText <FileText
strokeWidth={1.5} strokeWidth={1.5}
className="h-6 w-6 text-primary pl-1 " className="h-6 w-6 pl-1 text-primary "
aria-hidden="true" aria-hidden="true"
/> />
</DialogTitle> </DialogTitle>
@ -80,7 +80,7 @@ export default function GenericModal({
<div className="mt-2 flex h-full w-full"> <div className="mt-2 flex h-full w-full">
<Textarea <Textarea
ref={ref} ref={ref}
className=" h-[300px] w-full form-primary " className=" form-primary h-[300px] w-full "
value={myValue} value={myValue}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value); setMyValue(e.target.value);

View file

@ -81,7 +81,7 @@ export default function ButtonBox({
bgColor, bgColor,
height, height,
width, width,
padding padding,
)} )}
> >
<div <div
@ -98,7 +98,7 @@ export default function ButtonBox({
className={classNames( className={classNames(
"w-full break-words font-semibold text-background truncate-multiline", "w-full break-words font-semibold text-background truncate-multiline",
titleFontSize, titleFontSize,
marginTop marginTop,
)} )}
> >
{title} {title}

View file

@ -1,22 +1,18 @@
import { import {
XMarkIcon,
ArrowDownTrayIcon,
DocumentDuplicateIcon, DocumentDuplicateIcon,
ComputerDesktopIcon, ComputerDesktopIcon,
ArrowUpTrayIcon, ArrowUpTrayIcon,
ArrowLeftIcon, ArrowLeftIcon,
CommandLineIcon,
} from "@heroicons/react/24/outline"; } from "@heroicons/react/24/outline";
import { Fragment, useContext, useRef, useState } from "react"; import { useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext"; import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext"; import { TabsContext } from "../../contexts/tabsContext";
import ButtonBox from "./buttonBox"; import ButtonBox from "./buttonBox";
import { getExamples } from "../../controllers/API"; import { getExamples } from "../../controllers/API";
import { error } from "console";
import { alertContext } from "../../contexts/alertContext"; import { alertContext } from "../../contexts/alertContext";
import LoadingComponent from "../../components/loadingComponent"; import LoadingComponent from "../../components/loadingComponent";
import { FlowType } from "../../types/flow"; import { FlowType } from "../../types/flow";
import { classNames, snakeToSpaces, toNormalCase } from "../../utils"; import { classNames } from "../../utils";
import { import {
Dialog, Dialog,
DialogContent, DialogContent,
@ -26,7 +22,6 @@ import {
DialogTitle, DialogTitle,
DialogTrigger, DialogTrigger,
} from "../../components/ui/dialog"; } from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { IMPORT_DIALOG_SUBTITLE } from "../../constants"; import { IMPORT_DIALOG_SUBTITLE } from "../../constants";
export default function ImportModal() { export default function ImportModal() {
@ -160,7 +155,10 @@ export default function ImportModal() {
bgColor="bg-medium-emerald " bgColor="bg-medium-emerald "
description={example.description ?? "Prebuilt Examples"} description={example.description ?? "Prebuilt Examples"}
icon={ icon={
<DocumentDuplicateIcon strokeWidth={1.5} className="h-6 w-6 flex-shrink-0" /> <DocumentDuplicateIcon
strokeWidth={1.5}
className="h-6 w-6 flex-shrink-0"
/>
} }
onClick={() => { onClick={() => {
addFlow(example, false); addFlow(example, false);
@ -194,7 +192,7 @@ export default function ImportModal() {
fill="currentColor" fill="currentColor"
/> />
</svg> </svg>
<span className="ml-2 ">LangFlow Examples</span> <span className="ml-2 ">Langflow Examples</span>
</a> </a>
</div> </div>
</DialogFooter> </DialogFooter>

View file

@ -92,7 +92,7 @@ export default function TextAreaModal({
<div className="w-full overflow-hidden rounded-lg bg-background px-4 py-5 shadow sm:p-6"> <div className="w-full overflow-hidden rounded-lg bg-background px-4 py-5 shadow sm:p-6">
<textarea <textarea
ref={ref} ref={ref}
className="form-input h-full w-full form-primary" className="form-primary form-input h-full w-full"
value={myValue} value={myValue}
onChange={(e) => { onChange={(e) => {
setMyValue(e.target.value); setMyValue(e.target.value);

View file

@ -57,7 +57,7 @@ export default function CommunityPage() {
</div> </div>
</div> </div>
<span className="community-page-description-text"> <span className="community-page-description-text">
Discover and learn from shared examples by the LangFlow community. We Discover and learn from shared examples by the Langflow community. We
welcome new example contributions that can help our community explore welcome new example contributions that can help our community explore
new and powerful features. new and powerful features.
</span> </span>

View file

@ -15,9 +15,7 @@ export default function DisclosureComponent({
<Disclosure.Button className="components-disclosure-arrangement"> <Disclosure.Button className="components-disclosure-arrangement">
<div className="flex gap-4"> <div className="flex gap-4">
<Icon strokeWidth={1.5} size={22} className="text-primary" /> <Icon strokeWidth={1.5} size={22} className="text-primary" />
<span className="components-disclosure-title"> <span className="components-disclosure-title">{title}</span>
{title}
</span>
</div> </div>
<div className="components-disclosure-div"> <div className="components-disclosure-div">
{buttons.map((x, index) => ( {buttons.map((x, index) => (

View file

@ -111,10 +111,10 @@ export default function Page({ flow }: { flow: FlowType }) {
const { setExtraComponent, setExtraNavigation } = useContext(locationContext); const { setExtraComponent, setExtraNavigation } = useContext(locationContext);
const { setErrorData } = useContext(alertContext); const { setErrorData } = useContext(alertContext);
const [nodes, setNodes, onNodesChange] = useNodesState( const [nodes, setNodes, onNodesChange] = useNodesState(
flow.data?.nodes ?? [] flow.data?.nodes ?? [],
); );
const [edges, setEdges, onEdgesChange] = useEdgesState( const [edges, setEdges, onEdgesChange] = useEdgesState(
flow.data?.edges ?? [] flow.data?.edges ?? [],
); );
const { setViewport } = useReactFlow(); const { setViewport } = useReactFlow();
const edgeUpdateSuccessful = useRef(true); const edgeUpdateSuccessful = useRef(true);
@ -156,7 +156,7 @@ export default function Page({ flow }: { flow: FlowType }) {
}; };
}); });
}, },
[onEdgesChange, setNodes, setTabsState, tabId] [onEdgesChange, setNodes, setTabsState, tabId],
); );
const onNodesChangeMod = useCallback( const onNodesChangeMod = useCallback(
@ -171,7 +171,7 @@ export default function Page({ flow }: { flow: FlowType }) {
}; };
}); });
}, },
[onNodesChange, setTabsState, tabId] [onNodesChange, setTabsState, tabId],
); );
const onConnect = useCallback( const onConnect = useCallback(
@ -188,15 +188,15 @@ export default function Page({ flow }: { flow: FlowType }) {
: "stroke-foreground ", : "stroke-foreground ",
animated: params.targetHandle.split("|")[0] === "Text", animated: params.targetHandle.split("|")[0] === "Text",
}, },
eds eds,
) ),
); );
setNodes((x) => { setNodes((x) => {
let newX = _.cloneDeep(x); let newX = _.cloneDeep(x);
return newX; return newX;
}); });
}, },
[setEdges, setNodes, takeSnapshot] [setEdges, setNodes, takeSnapshot],
); );
const onNodeDragStart: NodeDragHandler = useCallback(() => { const onNodeDragStart: NodeDragHandler = useCallback(() => {
@ -230,7 +230,7 @@ export default function Page({ flow }: { flow: FlowType }) {
// Extract the data from the drag event and parse it as a JSON object // Extract the data from the drag event and parse it as a JSON object
let data: { type: string; node?: APIClassType } = JSON.parse( let data: { type: string; node?: APIClassType } = JSON.parse(
event.dataTransfer.getData("json") event.dataTransfer.getData("json"),
); );
// If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node // If data type is not "chatInput" or if there are no "chatInputNode" nodes present in the ReactFlow instance, create a new node
@ -275,7 +275,7 @@ export default function Page({ flow }: { flow: FlowType }) {
setNodes((nds) => nds.concat(newNode)); setNodes((nds) => nds.concat(newNode));
}, },
// Specify dependencies for useCallback // Specify dependencies for useCallback
[getNodeId, reactFlowInstance, setErrorData, setNodes, takeSnapshot] [getNodeId, reactFlowInstance, setErrorData, setNodes, takeSnapshot],
); );
useEffect(() => { useEffect(() => {
@ -291,11 +291,12 @@ export default function Page({ flow }: { flow: FlowType }) {
takeSnapshot(); takeSnapshot();
setEdges( setEdges(
edges.filter( edges.filter(
(ns) => !mynodes.some((n) => ns.source === n.id || ns.target === n.id) (ns) =>
) !mynodes.some((n) => ns.source === n.id || ns.target === n.id),
),
); );
}, },
[takeSnapshot, edges, setEdges] [takeSnapshot, edges, setEdges],
); );
const onEdgeUpdateStart = useCallback(() => { const onEdgeUpdateStart = useCallback(() => {
@ -309,7 +310,7 @@ export default function Page({ flow }: { flow: FlowType }) {
setEdges((els) => updateEdge(oldEdge, newConnection, els)); setEdges((els) => updateEdge(oldEdge, newConnection, els));
} }
}, },
[] [],
); );
const onEdgeUpdateEnd = useCallback((_, edge) => { const onEdgeUpdateEnd = useCallback((_, edge) => {

View file

@ -69,27 +69,29 @@ export default function ExtraSidebar() {
uploadFlow(); uploadFlow();
}} }}
> >
<FileUp strokeWidth={1.5} className="side-bar-button-size "></FileUp> <FileUp
strokeWidth={1.5}
className="side-bar-button-size "
></FileUp>
</button> </button>
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Export" side="top"> <ShadTooltip content="Export" side="top">
<button <button
className={classNames( className={classNames("extra-side-bar-buttons")}
"extra-side-bar-buttons"
)}
onClick={(event) => { onClick={(event) => {
openPopUp(<ExportModal />); openPopUp(<ExportModal />);
}} }}
> >
<FileDown strokeWidth={1.5} className="side-bar-button-size"></FileDown> <FileDown
strokeWidth={1.5}
className="side-bar-button-size"
></FileDown>
</button> </button>
</ShadTooltip> </ShadTooltip>
<ShadTooltip content="Code" side="top"> <ShadTooltip content="Code" side="top">
<button <button
className={classNames( className={classNames("extra-side-bar-buttons")}
"extra-side-bar-buttons"
)}
onClick={(event) => { onClick={(event) => {
openPopUp(<ApiModal flow={flows.find((f) => f.id === tabId)} />); openPopUp(<ApiModal flow={flows.find((f) => f.id === tabId)} />);
}} }}
@ -110,7 +112,8 @@ export default function ExtraSidebar() {
<Save <Save
strokeWidth={1.5} strokeWidth={1.5}
className={ className={
"side-bar-button-size" + (isPending ? " " : " extra-side-bar-save-disable") "side-bar-button-size" +
(isPending ? " " : " extra-side-bar-save-disable")
} }
></Save> ></Save>
</button> </button>

View file

@ -5,7 +5,6 @@ import { TabsContext } from "../../../../contexts/tabsContext";
import { useReactFlow } from "reactflow"; import { useReactFlow } from "reactflow";
import EditNodeModal from "../../../../modals/EditNodeModal"; import EditNodeModal from "../../../../modals/EditNodeModal";
import ShadTooltip from "../../../../components/ShadTooltipComponent"; import ShadTooltip from "../../../../components/ShadTooltipComponent";
import { EllipsisVerticalIcon } from "@heroicons/react/24/outline";
const NodeToolbarComponent = (props) => { const NodeToolbarComponent = (props) => {
const [nodeLength, setNodeLength] = useState( const [nodeLength, setNodeLength] = useState(

View file

@ -31,7 +31,7 @@ export default function FlowPage() {
href="https://logspace.ai/" href="https://logspace.ai/"
className="logspace-page-icon" className="logspace-page-icon"
> >
{version && <div className="mt-1">⛓️ LangFlow v{version}</div>} {version && <div className="mt-1">⛓️ Langflow v{version}</div>}
<div className={version ? "mt-2" : "mt-1"}>Created by Logspace</div> <div className={version ? "mt-2" : "mt-1"}>Created by Logspace</div>
</a> </a>
</div> </div>

View file

@ -28,7 +28,7 @@ export type TabsContextType = {
setTabsState: Dispatch<SetStateAction<TabsState>>; setTabsState: Dispatch<SetStateAction<TabsState>>;
paste: ( paste: (
selection: { nodes: any; edges: any }, selection: { nodes: any; edges: any },
position: { x: number; y: number; paneX?: number; paneY?: number } position: { x: number; y: number; paneX?: number; paneY?: number },
) => void; ) => void;
lastCopiedSelection: { nodes: any; edges: any }; lastCopiedSelection: { nodes: any; edges: any };
setLastCopiedSelection: (selection: { nodes: any; edges: any }) => void; setLastCopiedSelection: (selection: { nodes: any; edges: any }) => void;

View file

@ -484,7 +484,7 @@ export function cn(...inputs: ClassValue[]) {
export function measureTextHeight( export function measureTextHeight(
text: string, text: string,
width: number, width: number,
fontSize: number fontSize: number,
) { ) {
const charHeight = fontSize; const charHeight = fontSize;
const lineHeight = charHeight * 1.5; const lineHeight = charHeight * 1.5;
@ -511,7 +511,7 @@ export function toCamelCase(str: string) {
.map((word, index) => .map((word, index) =>
index === 0 index === 0
? word.toLowerCase() ? word.toLowerCase()
: word[0].toUpperCase() + word.slice(1).toLowerCase() : word[0].toUpperCase() + word.slice(1).toLowerCase(),
) )
.join(""); .join("");
} }
@ -572,7 +572,7 @@ export function getConnectedNodes(edge: Edge, nodes: Array<Node>): Array<Node> {
export function isValidConnection( export function isValidConnection(
{ source, target, sourceHandle, targetHandle }: Connection, { source, target, sourceHandle, targetHandle }: Connection,
reactFlowInstance: ReactFlowInstance reactFlowInstance: ReactFlowInstance,
) { ) {
if ( if (
sourceHandle.split("|")[0] === targetHandle.split("|")[0] || sourceHandle.split("|")[0] === targetHandle.split("|")[0] ||
@ -619,7 +619,7 @@ export function removeApiKeys(flow: FlowType): FlowType {
export function updateObject<T extends Record<string, any>>( export function updateObject<T extends Record<string, any>>(
reference: T, reference: T,
objectToUpdate: T objectToUpdate: T,
): T { ): T {
let clonedObject = _.cloneDeep(objectToUpdate); let clonedObject = _.cloneDeep(objectToUpdate);
// Loop through each key in the object to update // Loop through each key in the object to update
@ -650,7 +650,7 @@ export function debounce(func, wait) {
export function updateTemplate( export function updateTemplate(
reference: APITemplateType, reference: APITemplateType,
objectToUpdate: APITemplateType objectToUpdate: APITemplateType,
): APITemplateType { ): APITemplateType {
let clonedObject: APITemplateType = _.cloneDeep(reference); let clonedObject: APITemplateType = _.cloneDeep(reference);
@ -708,7 +708,7 @@ export function toTitleCase(str: string) {
.map((word, index) => { .map((word, index) => {
if (index === 0) { if (index === 0) {
return checkUpperWords( return checkUpperWords(
word[0].toUpperCase() + word.slice(1).toLowerCase() word[0].toUpperCase() + word.slice(1).toLowerCase(),
); );
} }
return checkUpperWords(word.toLowerCase()); return checkUpperWords(word.toLowerCase());
@ -720,7 +720,7 @@ export function toTitleCase(str: string) {
.map((word, index) => { .map((word, index) => {
if (index === 0) { if (index === 0) {
return checkUpperWords( return checkUpperWords(
word[0].toUpperCase() + word.slice(1).toLowerCase() word[0].toUpperCase() + word.slice(1).toLowerCase(),
); );
} }
return checkUpperWords(word.toLowerCase()); return checkUpperWords(word.toLowerCase());
@ -789,7 +789,7 @@ export function groupByFamily(data, baseClasses) {
}); });
let uniq = arrOfParent.filter( let uniq = arrOfParent.filter(
(item, index) => arrOfParent.indexOf(item) === index (item, index) => arrOfParent.indexOf(item) === index,
); );
Object.keys(data).map((d) => { Object.keys(data).map((d) => {
@ -809,7 +809,7 @@ export function groupByFamily(data, baseClasses) {
let groupedBy = arrOfType.filter((object, index, self) => { let groupedBy = arrOfType.filter((object, index, self) => {
const foundIndex = self.findIndex( const foundIndex = self.findIndex(
(o) => o.family === object.family && o.type === object.type (o) => o.family === object.family && o.type === object.type,
); );
return foundIndex === index; return foundIndex === index;
}); });
@ -835,7 +835,7 @@ export function buildTweaks(flow) {
} }
export function validateNode( export function validateNode(
n: NodeType, n: NodeType,
reactFlowInstance: ReactFlowInstance reactFlowInstance: ReactFlowInstance,
): Array<string> { ): Array<string> {
if (!n.data?.node?.template || !Object.keys(n.data.node.template)) { if (!n.data?.node?.template || !Object.keys(n.data.node.template)) {
return [ return [
@ -861,16 +861,16 @@ export function validateNode(
.some( .some(
(e) => (e) =>
e.targetHandle.split("|")[1] === t && e.targetHandle.split("|")[1] === t &&
e.targetHandle.split("|")[2] === n.id e.targetHandle.split("|")[2] === n.id,
) )
? [ ? [
`${type} is missing ${ `${type} is missing ${
template.display_name || toNormalCase(template[t].name) template.display_name || toNormalCase(template[t].name)
}.`, }.`,
] ]
: [] : [],
), ),
[] as string[] [] as string[],
); );
} }
@ -895,7 +895,7 @@ export function getRandomDescription(): string {
export function getRandomName( export function getRandomName(
retry: number = 0, retry: number = 0,
noSpace: boolean = false, noSpace: boolean = false,
maxRetries: number = 3 maxRetries: number = 3,
): string { ): string {
const left: string[] = ADJECTIVES; const left: string[] = ADJECTIVES;
const right: string[] = NOUNS; const right: string[] = NOUNS;