Merge remote-tracking branch 'origin/form_io' into python_custom_node_component

Merge remote-tracking branch 'origin/form_io' into python_custom_node_component

- Updated the README files to correct the spelling of "Langflow" in various places.
- Added a new `.env.example` file for reference and configuration.
- Updated the CONTRIBUTING.md file to use "Langflow" instead of "LangFlow".
- Updated the GCP_DEPLOYMENT.md file to use the correct GitHub repository URL.
- Updated the README file to use "Langflow" instead of "LangFlow" and corrected the formatting of the table of contents.
- Updated the CLI usage instructions in the README file to use "Langflow" and provided more detailed explanations of each option.
- Added a section on Deployment in the README file with instructions for deploying Langflow on Google Cloud Platform.
- Updated the "Creating Flows" section in the README file to use "Langflow" instead of "LangFlow" and corrected the link to the LangChain components.
- Updated the "Contributing" section in the README file to use "Langflow" instead of "LangFlow" and corrected the link to the contributing guidelines.
- Updated the "License" section in the README file to use "Langflow" instead of "LangFlow".
- Updated the version of the "anyio" package in the poetry.lock file to 3.7.1.

Merge remote-tracking branch 'origin/form_io' into python_custom_node_component

- Updated the README files to correct the spelling of "Langflow" in various places.
- Added a new `.env.example` file for reference and configuration.
- Updated the CONTRIBUTING.md file to use "Langflow" instead of "Langflow".
- Updated the GCP_DEPLOYMENT.md file to use the correct GitHub repository URL.
- Updated the README file to use "Langflow" instead of "Langflow" and corrected the formatting of the table of contents.
- Updated the CLI usage instructions in the README file to use "Langflow" and provided more detailed explanations of each option.
- Added a section on Deployment in the README file with instructions for deploying Langflow on Google Cloud Platform.
- Updated the "Creating Flows" section in the README file to use "Langflow" instead of "Langflow" and corrected the link to the LangChain components.
- Updated the "Contributing" section in the README file to use "Langflow" instead of "Langflow" and corrected the link to the contributing guidelines.
- Updated the "License" section in the README file to use "Langflow" instead of "Langflow".
- Updated the version of the "anyio" package in the poetry.lock file to 3.7.1.

Merge remote-tracking branch 'origin/form_io' into python_custom_node_component

- Updated the README files to correct the spelling of "Langflow" in various places.
- Added a new `.env.example` file for reference and configuration.
- Updated the CONTRIBUTING.md file to use "Langflow" instead of "Langflow".
- Updated the GCP_DEPLOYMENT.md file to use the correct GitHub repository URL.
- Updated the README file to use "Langflow" instead of "Langflow" and corrected the formatting of the table of contents.
- Updated the CLI usage instructions in the README file to use "Langflow" and provided more detailed explanations of each option.
- Added a section on Deployment in the README file with instructions for deploying Langflow on Google Cloud Platform.
- Updated the "Creating Flows" section in the README file to use "Langflow" instead of "Langflow" and corrected the link to the LangChain components.
- Updated the "Contributing" section in the README file to use "
This commit is contained in:
gustavoschaedler 2023-07-07 22:55:17 +01:00
commit da9764b3c5
126 changed files with 3072 additions and 1372 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

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
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
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.

View file

@ -13,7 +13,7 @@ This script sets up a Debian-based VM with the Langflow package, Nginx, and the
## Spot/Preemptible Instance
[![Open in Cloud Shell - Spot Instance](https://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/genome21/langflow&working_dir=scripts&shellonly=true&tutorial=walkthroughtutorial_spot.md)
[![Open in Cloud Shell - Spot Instance](https://gstatic.com/cloudssh/images/open-btn.svg)](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/logspace-ai/langflow&working_dir=scripts&shellonly=true&tutorial=walkthroughtutorial_spot.md)
When running as a [spot (preemptible) instance](https://cloud.google.com/compute/docs/instances/preemptible), the code and VM will behave the same way as in a regular instance, executing the startup script to configure the environment, install necessary dependencies, and run the Langflow application. However, **due to the nature of spot instances, the VM may be terminated at any time if Google Cloud needs to reclaim the resources**. This makes spot instances suitable for fault-tolerant, stateless, or interruptible workloads that can handle unexpected terminations and restarts.

View file

@ -1,6 +1,6 @@
<!-- Title -->
# ⛓️ LangFlow
# ⛓️ Langflow
~ An effortless way to experiment and prototype [LangChain](https://github.com/hwchase17/langchain) pipelines ~
@ -16,7 +16,7 @@
<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://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>
<a href="https://github.com/logspace-ai/langflow">
@ -26,9 +26,26 @@
<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>
You can install LangFlow from pip:
You can install Langflow from pip:
```shell
pip install langflow
@ -41,9 +58,51 @@ python -m langflow
```
or
```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
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 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.
@ -176,13 +235,13 @@ from langflow import load_flow_from_json
flow = load_flow_from_json("path/to/flow.json")
# Now you can use it like any chain
flow("Hey, have you heard of LangFlow?")
flow("Hey, have you heard of Langflow?")
```
## 👋 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! 🦾
@ -195,4 +254,4 @@ Join our [Discord](https://discord.com/invite/EqksyE2EX9) server to ask question
## 📄 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.

274
poetry.lock generated
View file

@ -170,14 +170,14 @@ typing-extensions = ">=4.1.1"
[[package]]
name = "anyio"
version = "3.7.0"
version = "3.7.1"
description = "High level compatibility layer for multiple asynchronous event loop implementations"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"},
{file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"},
{file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"},
{file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"},
]
[package.dependencies]
@ -186,7 +186,7 @@ idna = ">=2.8"
sniffio = ">=1.1"
[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)"]
trio = ["trio (<0.22)"]
@ -1609,14 +1609,14 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]]
name = "google-api-python-client"
version = "2.91.0"
version = "2.92.0"
description = "Google API Client Library for Python"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-api-python-client-2.91.0.tar.gz", hash = "sha256:d9385ad6e7f95eecd40f7c81e3abfe4b6ad3a84f2c16bcdb66fb7b8dd814ed56"},
{file = "google_api_python_client-2.91.0-py2.py3-none-any.whl", hash = "sha256:6959d21d4b20c0f65c69662ca7b6a8a02fc08f3e7f72d70b28ae3e6e3a5f9ab2"},
{file = "google-api-python-client-2.92.0.tar.gz", hash = "sha256:f38a6e106a7417719715506d36f0a233ec253335e422bda311352866a86c4187"},
{file = "google_api_python_client-2.92.0-py2.py3-none-any.whl", hash = "sha256:e0b74ed5fa9bdb07a66fb030d3f4cae550ed1c07e23600d86450d3c3c5efae51"},
]
[package.dependencies]
@ -1761,14 +1761,14 @@ grpc = ["grpcio (>=1.38.0,<2.0dev)"]
[[package]]
name = "google-cloud-resource-manager"
version = "1.10.1"
version = "1.10.2"
description = "Google Cloud Resource Manager API client library"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "google-cloud-resource-manager-1.10.1.tar.gz", hash = "sha256:c974fb6f9810476cf7b63ea89394c1a8df47f7f2dc2303e728bb74b500bcde67"},
{file = "google_cloud_resource_manager-1.10.1-py2.py3-none-any.whl", hash = "sha256:41a2204532f084c707fde0bc1a9bc95c7e0b739d7072dd0b8a25106667a56184"},
{file = "google-cloud-resource-manager-1.10.2.tar.gz", hash = "sha256:9a7bdd0347ad553376cc66ad317c5223d1ae04bdcf74edcbfcd12605cff7b510"},
{file = "google_cloud_resource_manager-1.10.2-py2.py3-none-any.whl", hash = "sha256:9e074c28326bd1632f1a270c20cfea1ffe98f49cf821033e65bdac55661ffbd5"},
]
[package.dependencies]
@ -2808,14 +2808,14 @@ websockets = ["websockets"]
[[package]]
name = "jina-hubble-sdk"
version = "0.38.0"
version = "0.39.0"
description = "SDK for Hubble API at Jina AI."
category = "main"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "jina-hubble-sdk-0.38.0.tar.gz", hash = "sha256:1667917ed16d75eddd1e0d3b8e9d78ffd611de59500abeca48b05040c7571c4c"},
{file = "jina_hubble_sdk-0.38.0-py3-none-any.whl", hash = "sha256:f887f5a5839b530b59393fe56e9b48d406f52a178739d3a5799c8e201bcf4015"},
{file = "jina-hubble-sdk-0.39.0.tar.gz", hash = "sha256:9021417794a6d3cf3fad8a880cf668a3a986b9d53d5be5fa391aae1767a5b9b0"},
{file = "jina_hubble_sdk-0.39.0-py3-none-any.whl", hash = "sha256:b0edd4b62d742c27d726d68f65a041b3c4d9aa6b3b9b203d5b0e729904161e3e"},
]
[package.dependencies]
@ -3070,96 +3070,100 @@ dev = ["Sphinx (==5.3.0)", "colorama (==0.4.5)", "colorama (==0.4.6)", "freezegu
[[package]]
name = "lxml"
version = "4.9.2"
version = "4.9.3"
description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
category = "main"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
files = [
{file = "lxml-4.9.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:76cf573e5a365e790396a5cc2b909812633409306c6531a6877c59061e42c4f2"},
{file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b1f42b6921d0e81b1bcb5e395bc091a70f41c4d4e55ba99c6da2b31626c44892"},
{file = "lxml-4.9.2-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9f102706d0ca011de571de32c3247c6476b55bb6bc65a20f682f000b07a4852a"},
{file = "lxml-4.9.2-cp27-cp27m-win32.whl", hash = "sha256:8d0b4612b66ff5d62d03bcaa043bb018f74dfea51184e53f067e6fdcba4bd8de"},
{file = "lxml-4.9.2-cp27-cp27m-win_amd64.whl", hash = "sha256:4c8f293f14abc8fd3e8e01c5bd86e6ed0b6ef71936ded5bf10fe7a5efefbaca3"},
{file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2899456259589aa38bfb018c364d6ae7b53c5c22d8e27d0ec7609c2a1ff78b50"},
{file = "lxml-4.9.2-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6749649eecd6a9871cae297bffa4ee76f90b4504a2a2ab528d9ebe912b101975"},
{file = "lxml-4.9.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:a08cff61517ee26cb56f1e949cca38caabe9ea9fbb4b1e10a805dc39844b7d5c"},
{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.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8340225bd5e7a701c0fa98284c849c9b9fc9238abf53a0ebd90900f25d39a4e4"},
{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.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:699a9af7dffaf67deeae27b2112aa06b41c370d5e7633e0ee0aea2e0b6c211f7"},
{file = "lxml-4.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9cc34af337a97d470040f99ba4282f6e6bac88407d021688a5d585e44a23184"},
{file = "lxml-4.9.2-cp310-cp310-win32.whl", hash = "sha256:d02a5399126a53492415d4906ab0ad0375a5456cc05c3fc0fc4ca11771745cda"},
{file = "lxml-4.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:a38486985ca49cfa574a507e7a2215c0c780fd1778bb6290c21193b7211702ab"},
{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.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2a87fa548561d2f4643c99cd13131acb607ddabb70682dcf1dff5f71f781a4bf"},
{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.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:3efea981d956a6f7173b4659849f55081867cf897e719f57383698af6f618a92"},
{file = "lxml-4.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:df0623dcf9668ad0445e0558a21211d4e9a149ea8f5666917c8eeec515f0a6d1"},
{file = "lxml-4.9.2-cp311-cp311-win32.whl", hash = "sha256:da248f93f0418a9e9d94b0080d7ebc407a9a5e6d0b57bb30db9b5cc28de1ad33"},
{file = "lxml-4.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:3818b8e2c4b5148567e1b09ce739006acfaa44ce3156f8cbbc11062994b8e8dd"},
{file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ca989b91cf3a3ba28930a9fc1e9aeafc2a395448641df1f387a2d394638943b0"},
{file = "lxml-4.9.2-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:822068f85e12a6e292803e112ab876bc03ed1f03dddb80154c395f891ca6b31e"},
{file = "lxml-4.9.2-cp35-cp35m-win32.whl", hash = "sha256:be7292c55101e22f2a3d4d8913944cbea71eea90792bf914add27454a13905df"},
{file = "lxml-4.9.2-cp35-cp35m-win_amd64.whl", hash = "sha256:998c7c41910666d2976928c38ea96a70d1aa43be6fe502f21a651e17483a43c5"},
{file = "lxml-4.9.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:b26a29f0b7fc6f0897f043ca366142d2b609dc60756ee6e4e90b5f762c6adc53"},
{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.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:689bb688a1db722485e4610a503e3e9210dcc20c520b45ac8f7533c837be76fe"},
{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.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:36c3c175d34652a35475a73762b545f4527aec044910a651d2bf50de9c3352b1"},
{file = "lxml-4.9.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a35f8b7fa99f90dd2f5dc5a9fa12332642f087a7641289ca6c40d6e1a2637d8e"},
{file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:58bfa3aa19ca4c0f28c5dde0ff56c520fbac6f0daf4fac66ed4c8d2fb7f22e74"},
{file = "lxml-4.9.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc718cd47b765e790eecb74d044cc8d37d58562f6c314ee9484df26276d36a38"},
{file = "lxml-4.9.2-cp36-cp36m-win32.whl", hash = "sha256:d5bf6545cd27aaa8a13033ce56354ed9e25ab0e4ac3b5392b763d8d04b08e0c5"},
{file = "lxml-4.9.2-cp36-cp36m-win_amd64.whl", hash = "sha256:3ab9fa9d6dc2a7f29d7affdf3edebf6ece6fb28a6d80b14c3b2fb9d39b9322c3"},
{file = "lxml-4.9.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:05ca3f6abf5cf78fe053da9b1166e062ade3fa5d4f92b4ed688127ea7d7b1d03"},
{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.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:04876580c050a8c5341d706dd464ff04fd597095cc8c023252566a8826505726"},
{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.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2a29ba94d065945944016b6b74e538bdb1751a1db6ffb80c9d3c2e40d6fa9894"},
{file = "lxml-4.9.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a82d05da00a58b8e4c0008edbc8a4b6ec5a4bc1e2ee0fb6ed157cf634ed7fa45"},
{file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:223f4232855ade399bd409331e6ca70fb5578efef22cf4069a6090acc0f53c0e"},
{file = "lxml-4.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d17bc7c2ccf49c478c5bdd447594e82692c74222698cfc9b5daae7ae7e90743b"},
{file = "lxml-4.9.2-cp37-cp37m-win32.whl", hash = "sha256:b64d891da92e232c36976c80ed7ebb383e3f148489796d8d31a5b6a677825efe"},
{file = "lxml-4.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:a0a336d6d3e8b234a3aae3c674873d8f0e720b76bc1d9416866c41cd9500ffb9"},
{file = "lxml-4.9.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:da4dd7c9c50c059aba52b3524f84d7de956f7fef88f0bafcf4ad7dde94a064e8"},
{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.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:e5168986b90a8d1f2f9dc1b841467c74221bd752537b99761a93d2d981e04889"},
{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.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:13598ecfbd2e86ea7ae45ec28a2a54fb87ee9b9fdb0f6d343297d8e548392c03"},
{file = "lxml-4.9.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:880bbbcbe2fca64e2f4d8e04db47bcdf504936fa2b33933efd945e1b429bea8c"},
{file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7d2278d59425777cfcb19735018d897ca8303abe67cc735f9f97177ceff8027f"},
{file = "lxml-4.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5344a43228767f53a9df6e5b253f8cdca7dfc7b7aeae52551958192f56d98457"},
{file = "lxml-4.9.2-cp38-cp38-win32.whl", hash = "sha256:925073b2fe14ab9b87e73f9a5fde6ce6392da430f3004d8b72cc86f746f5163b"},
{file = "lxml-4.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:9b22c5c66f67ae00c0199f6055705bc3eb3fcb08d03d2ec4059a2b1b25ed48d7"},
{file = "lxml-4.9.2-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:5f50a1c177e2fa3ee0667a5ab79fdc6b23086bc8b589d90b93b4bd17eb0e64d1"},
{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.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:63da2ccc0857c311d764e7d3d90f429c252e83b52d1f8f1d1fe55be26827d1f4"},
{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.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2e430cd2824f05f2d4f687701144556646bae8f249fd60aa1e4c768ba7018947"},
{file = "lxml-4.9.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6804daeb7ef69e7b36f76caddb85cccd63d0c56dedb47555d2fc969e2af6a1a5"},
{file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a6e441a86553c310258aca15d1c05903aaf4965b23f3bc2d55f200804e005ee5"},
{file = "lxml-4.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ca34efc80a29351897e18888c71c6aca4a359247c87e0b1c7ada14f0ab0c0fb2"},
{file = "lxml-4.9.2-cp39-cp39-win32.whl", hash = "sha256:6b418afe5df18233fc6b6093deb82a32895b6bb0b1155c2cdb05203f583053f1"},
{file = "lxml-4.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:f1496ea22ca2c830cbcbd473de8f114a320da308438ae65abad6bab7867fe38f"},
{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.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.2-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:16efd54337136e8cd72fb9485c368d91d77a47ee2d42b057564aae201257d419"},
{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.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.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:efa29c2fe6b4fdd32e8ef81c1528506895eca86e1d8c4657fda04c9b3786ddf9"},
{file = "lxml-4.9.2-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7e91ee82f4199af8c43d8158024cbdff3d931df350252288f0d4ce656df7f3b5"},
{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.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.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7b515674acfdcadb0eb5d00d8a709868173acece5cb0be3dd165950cbfdf5409"},
{file = "lxml-4.9.2.tar.gz", hash = "sha256:2455cfaeb7ac70338b3257f41e21f0724f4b5b0c0e7702da67ee6c3640835b67"},
{file = "lxml-4.9.3-cp27-cp27m-macosx_11_0_x86_64.whl", hash = "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c"},
{file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d"},
{file = "lxml-4.9.3-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef"},
{file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb"},
{file = "lxml-4.9.3-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e"},
{file = "lxml-4.9.3-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991"},
{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.3-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8"},
{file = "lxml-4.9.3-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76"},
{file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23"},
{file = "lxml-4.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f"},
{file = "lxml-4.9.3-cp310-cp310-win32.whl", hash = "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85"},
{file = "lxml-4.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d"},
{file = "lxml-4.9.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5"},
{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.3-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f"},
{file = "lxml-4.9.3-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b"},
{file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120"},
{file = "lxml-4.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6"},
{file = "lxml-4.9.3-cp311-cp311-win32.whl", hash = "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305"},
{file = "lxml-4.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc"},
{file = "lxml-4.9.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4"},
{file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be"},
{file = "lxml-4.9.3-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13"},
{file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9"},
{file = "lxml-4.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5"},
{file = "lxml-4.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8"},
{file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7"},
{file = "lxml-4.9.3-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2"},
{file = "lxml-4.9.3-cp35-cp35m-win32.whl", hash = "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d"},
{file = "lxml-4.9.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833"},
{file = "lxml-4.9.3-cp36-cp36m-macosx_11_0_x86_64.whl", hash = "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12"},
{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.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c"},
{file = "lxml-4.9.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584"},
{file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287"},
{file = "lxml-4.9.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458"},
{file = "lxml-4.9.3-cp36-cp36m-win32.whl", hash = "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477"},
{file = "lxml-4.9.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf"},
{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.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693"},
{file = "lxml-4.9.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4"},
{file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a"},
{file = "lxml-4.9.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02"},
{file = "lxml-4.9.3-cp37-cp37m-win32.whl", hash = "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f"},
{file = "lxml-4.9.3-cp37-cp37m-win_amd64.whl", hash = "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52"},
{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.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42"},
{file = "lxml-4.9.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa"},
{file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40"},
{file = "lxml-4.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7"},
{file = "lxml-4.9.3-cp38-cp38-win32.whl", hash = "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574"},
{file = "lxml-4.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96"},
{file = "lxml-4.9.3-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340"},
{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.3-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d"},
{file = "lxml-4.9.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432"},
{file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69"},
{file = "lxml-4.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50"},
{file = "lxml-4.9.3-cp39-cp39-win32.whl", hash = "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2"},
{file = "lxml-4.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2"},
{file = "lxml-4.9.3-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35"},
{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.3-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-macosx_11_0_x86_64.whl", hash = "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b"},
{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.3-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b"},
{file = "lxml-4.9.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a"},
{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]
cssselect = ["cssselect (>=0.7)"]
html5 = ["html5lib"]
htmlsoup = ["BeautifulSoup4"]
source = ["Cython (>=0.29.7)"]
source = ["Cython (>=0.29.35)"]
[[package]]
name = "lz4"
@ -4625,14 +4629,14 @@ twisted = ["twisted"]
[[package]]
name = "prompt-toolkit"
version = "3.0.38"
version = "3.0.39"
description = "Library for building powerful interactive command lines in Python"
category = "dev"
optional = false
python-versions = ">=3.7.0"
files = [
{file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"},
{file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"},
{file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"},
{file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"},
]
[package.dependencies]
@ -5029,48 +5033,48 @@ files = [
[[package]]
name = "pydantic"
version = "1.10.10"
version = "1.10.11"
description = "Data validation and settings management using python type hints"
category = "main"
optional = false
python-versions = ">=3.7"
files = [
{file = "pydantic-1.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adad1ee4ab9888f12dac2529276704e719efcf472e38df7813f5284db699b4ec"},
{file = "pydantic-1.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a7db03339893feef2092ff7b1afc9497beed15ebd4af84c3042a74abce02d48"},
{file = "pydantic-1.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67b3714b97ff84b2689654851c2426389bcabfac9080617bcf4306c69db606f6"},
{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.10-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20a3b30fd255eeeb63caa9483502ba96b7795ce5bf895c6a179b3d909d9f53a6"},
{file = "pydantic-1.10.10-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db4c7f7e60ca6f7d6c1785070f3e5771fcb9b2d88546e334d2f2c3934d949028"},
{file = "pydantic-1.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:a2d5be50ac4a0976817144c7d653e34df2f9436d15555189f5b6f61161d64183"},
{file = "pydantic-1.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:566a04ba755e8f701b074ffb134ddb4d429f75d5dced3fbd829a527aafe74c71"},
{file = "pydantic-1.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f79db3652ed743309f116ba863dae0c974a41b688242482638b892246b7db21d"},
{file = "pydantic-1.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62376890b819bebe3c717a9ac841a532988372b7e600e76f75c9f7c128219d5"},
{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.10-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:990027e77cda6072a566e433b6962ca3b96b4f3ae8bd54748e9d62a58284d9d7"},
{file = "pydantic-1.10.10-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8c40964596809eb616d94f9c7944511f620a1103d63d5510440ed2908fc410af"},
{file = "pydantic-1.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:ea9eebc2ebcba3717e77cdeee3f6203ffc0e78db5f7482c68b1293e8cc156e5e"},
{file = "pydantic-1.10.10-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:762aa598f79b4cac2f275d13336b2dd8662febee2a9c450a49a2ab3bec4b385f"},
{file = "pydantic-1.10.10-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dab5219659f95e357d98d70577b361383057fb4414cfdb587014a5f5c595f7b"},
{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.10-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b69f9138dec566962ec65623c9d57bee44412d2fc71065a5f3ebb3820bdeee96"},
{file = "pydantic-1.10.10-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7aa75d1bd9cc275cf9782f50f60cddaf74cbaae19b6ada2a28e737edac420312"},
{file = "pydantic-1.10.10-cp37-cp37m-win_amd64.whl", hash = "sha256:9f62a727f5c590c78c2d12fda302d1895141b767c6488fe623098f8792255fe5"},
{file = "pydantic-1.10.10-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:aac218feb4af73db8417ca7518fb3bade4534fcca6e3fb00f84966811dd94450"},
{file = "pydantic-1.10.10-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:88546dc10a40b5b52cae87d64666787aeb2878f9a9b37825aedc2f362e7ae1da"},
{file = "pydantic-1.10.10-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c41bbaae89e32fc582448e71974de738c055aef5ab474fb25692981a08df808a"},
{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.10-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e088e3865a2270ecbc369924cd7d9fbc565667d9158e7f304e4097ebb9cf98dd"},
{file = "pydantic-1.10.10-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3403a090db45d4027d2344859d86eb797484dfda0706cf87af79ace6a35274ef"},
{file = "pydantic-1.10.10-cp38-cp38-win_amd64.whl", hash = "sha256:e0014e29637125f4997c174dd6167407162d7af0da73414a9340461ea8573252"},
{file = "pydantic-1.10.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9965e49c6905840e526e5429b09e4c154355b6ecc0a2f05492eda2928190311d"},
{file = "pydantic-1.10.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:748d10ab6089c5d196e1c8be9de48274f71457b01e59736f7a09c9dc34f51887"},
{file = "pydantic-1.10.10-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86936c383f7c38fd26d35107eb669c85d8f46dfceae873264d9bab46fe1c7dde"},
{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.10-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:409b810f387610cc7405ab2fa6f62bdf7ea485311845a242ebc0bd0496e7e5ac"},
{file = "pydantic-1.10.10-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ce937a2a2c020bcad1c9fde02892392a1123de6dda906ddba62bfe8f3e5989a2"},
{file = "pydantic-1.10.10-cp39-cp39-win_amd64.whl", hash = "sha256:37ebddef68370e6f26243acc94de56d291e01227a67b2ace26ea3543cf53dd5f"},
{file = "pydantic-1.10.10-py3-none-any.whl", hash = "sha256:a5939ec826f7faec434e2d406ff5e4eaf1716eb1f247d68cd3d0b3612f7b4c8a"},
{file = "pydantic-1.10.10.tar.gz", hash = "sha256:3b8d5bd97886f9eb59260594207c9f57dce14a6f869c6ceea90188715d29921a"},
{file = "pydantic-1.10.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ff44c5e89315b15ff1f7fdaf9853770b810936d6b01a7bcecaa227d2f8fe444f"},
{file = "pydantic-1.10.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6c098d4ab5e2d5b3984d3cb2527e2d6099d3de85630c8934efcfdc348a9760e"},
{file = "pydantic-1.10.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16928fdc9cb273c6af00d9d5045434c39afba5f42325fb990add2c241402d151"},
{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.11-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9baf78b31da2dc3d3f346ef18e58ec5f12f5aaa17ac517e2ffd026a92a87588"},
{file = "pydantic-1.10.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:373c0840f5c2b5b1ccadd9286782852b901055998136287828731868027a724f"},
{file = "pydantic-1.10.11-cp310-cp310-win_amd64.whl", hash = "sha256:c3339a46bbe6013ef7bdd2844679bfe500347ac5742cd4019a88312aa58a9847"},
{file = "pydantic-1.10.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08a6c32e1c3809fbc49debb96bf833164f3438b3696abf0fbeceb417d123e6eb"},
{file = "pydantic-1.10.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a451ccab49971af043ec4e0d207cbc8cbe53dbf148ef9f19599024076fe9c25b"},
{file = "pydantic-1.10.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b02d24f7b2b365fed586ed73582c20f353a4c50e4be9ba2c57ab96f8091ddae"},
{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.11-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e297897eb4bebde985f72a46a7552a7556a3dd11e7f76acda0c1093e3dbcf216"},
{file = "pydantic-1.10.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d185819a7a059550ecb85d5134e7d40f2565f3dd94cfd870132c5f91a89cf58c"},
{file = "pydantic-1.10.11-cp311-cp311-win_amd64.whl", hash = "sha256:4400015f15c9b464c9db2d5d951b6a780102cfa5870f2c036d37c23b56f7fc1b"},
{file = "pydantic-1.10.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2417de68290434461a266271fc57274a138510dca19982336639484c73a07af6"},
{file = "pydantic-1.10.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:331c031ba1554b974c98679bd0780d89670d6fd6f53f5d70b10bdc9addee1713"},
{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.11-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:44e51ba599c3ef227e168424e220cd3e544288c57829520dc90ea9cb190c3248"},
{file = "pydantic-1.10.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d7781f1d13b19700b7949c5a639c764a077cbbdd4322ed505b449d3ca8edcb36"},
{file = "pydantic-1.10.11-cp37-cp37m-win_amd64.whl", hash = "sha256:7522a7666157aa22b812ce14c827574ddccc94f361237ca6ea8bb0d5c38f1629"},
{file = "pydantic-1.10.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc64eab9b19cd794a380179ac0e6752335e9555d214cfcb755820333c0784cb3"},
{file = "pydantic-1.10.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8dc77064471780262b6a68fe67e013298d130414d5aaf9b562c33987dbd2cf4f"},
{file = "pydantic-1.10.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe429898f2c9dd209bd0632a606bddc06f8bce081bbd03d1c775a45886e2c1cb"},
{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.11-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ef55392ec4bb5721f4ded1096241e4b7151ba6d50a50a80a2526c854f42e6a2f"},
{file = "pydantic-1.10.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:41e0bb6efe86281623abbeeb0be64eab740c865388ee934cd3e6a358784aca6e"},
{file = "pydantic-1.10.11-cp38-cp38-win_amd64.whl", hash = "sha256:265a60da42f9f27e0b1014eab8acd3e53bd0bad5c5b4884e98a55f8f596b2c19"},
{file = "pydantic-1.10.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:469adf96c8e2c2bbfa655fc7735a2a82f4c543d9fee97bd113a7fb509bf5e622"},
{file = "pydantic-1.10.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e6cbfbd010b14c8a905a7b10f9fe090068d1744d46f9e0c021db28daeb8b6de1"},
{file = "pydantic-1.10.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abade85268cc92dff86d6effcd917893130f0ff516f3d637f50dadc22ae93999"},
{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.11-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:787cf23e5a0cde753f2eabac1b2e73ae3844eb873fd1f5bdbff3048d8dbb7604"},
{file = "pydantic-1.10.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:174899023337b9fc685ac8adaa7b047050616136ccd30e9070627c1aaab53a13"},
{file = "pydantic-1.10.11-cp39-cp39-win_amd64.whl", hash = "sha256:1954f8778489a04b245a1e7b8b22a9d3ea8ef49337285693cf6959e4b757535e"},
{file = "pydantic-1.10.11-py3-none-any.whl", hash = "sha256:008c5e266c8aada206d0627a011504e14268a62091450210eda7c07fabe6963e"},
{file = "pydantic-1.10.11.tar.gz", hash = "sha256:f66d479cf7eb331372c470614be6511eae96f1f120344c25f3f9bb59fb1b5528"},
]
[package.dependencies]
@ -7043,14 +7047,14 @@ files = [
[[package]]
name = "types-pillow"
version = "9.5.0.5"
version = "9.5.0.6"
description = "Typing stubs for Pillow"
category = "dev"
optional = false
python-versions = "*"
files = [
{file = "types-Pillow-9.5.0.5.tar.gz", hash = "sha256:de9877aa1e6226b6479459ca84df02fd7e999b970c79cfee3b8298840336e77c"},
{file = "types_Pillow-9.5.0.5-py3-none-any.whl", hash = "sha256:2b17f95c5c16e4962e4032bdb95494766a85569fa278ee21e5fcbbd318e9ccd2"},
{file = "types-Pillow-9.5.0.6.tar.gz", hash = "sha256:6a0cad40686e5c35fe7ada70f52bd3970395d31ece33486609e5420e820a9e4e"},
{file = "types_Pillow-9.5.0.6-py3-none-any.whl", hash = "sha256:1d238abaa9d529b04941d805b7f4d3f7df30702bb14521ec507617f117406fb4"},
]
[[package]]

View file

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

View file

@ -35,7 +35,7 @@ fi
# Create a firewall rule to allow IAP traffic
firewall_iap_exists=$(gcloud compute firewall-rules list --filter="name=allow-iap" --format="value(name)")
if [[ -z "$firewall_iap_exists" ]]; then
gcloud compute firewall-rules create allow-iap --network $VPC_NAME --allow tcp:80,tcp:443,tcp:22,:tcp:3389 --source-ranges 35.235.240.0/20 --direction INGRESS
gcloud compute firewall-rules create allow-iap --network $VPC_NAME --allow tcp:80,tcp:443,tcp:22,tcp:3389 --source-ranges 35.235.240.0/20 --direction INGRESS
fi
# Define the startup script as a multiline Bash here-doc

View file

@ -1,3 +1,4 @@
import os
import sys
import time
import httpx
@ -33,6 +34,10 @@ def update_settings(
remove_api_keys: bool = False,
):
"""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:
settings.update_from_yaml(config, dev=dev)
if database_url:
@ -43,6 +48,26 @@ def update_settings(
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():
"""
Deploy Langflow server on Jina AI Cloud
@ -91,19 +116,27 @@ def serve_on_jcloud():
@app.command()
def serve(
host: str = typer.Option("127.0.0.1", help="Host to bind the server to."),
workers: int = typer.Option(1, help="Number of worker processes."),
host: str = typer.Option(
"127.0.0.1", help="Host to bind the server to.", envvar="LANGFLOW_HOST"
),
workers: int = typer.Option(
1, help="Number of worker processes.", envvar="LANGFLOW_WORKERS"
),
timeout: int = typer.Option(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."),
# .env file param
env_file: Path = typer.Option(
".env", help="Path to the .env file containing environment variables."
),
log_level: str = typer.Option("critical", help="Logging level."),
log_file: Path = typer.Option("logs/langflow.log", help="Path to the log file."),
cache: str = typer.Argument(
envvar="LANGCHAIN_CACHE",
log_level: str = typer.Option(
"critical", help="Logging level.", envvar="LANGFLOW_LOG_LEVEL"
),
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)",
default="SQLiteCache",
),
@ -112,27 +145,35 @@ def serve(
database_url: str = typer.Option(
None,
help="Database URL to connect to. If not provided, a local SQLite database will be used.",
envvar="LANGFLOW_DATABASE_URL",
),
path: str = typer.Option(
None,
help="Path to the frontend directory containing build files. This is for development purposes only.",
envvar="LANGFLOW_FRONTEND_PATH",
),
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(
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.
"""
# override env variables with .env file
if env_file:
load_dotenv(env_file, override=True)
load_params()
if jcloud:
return serve_on_jcloud()
load_dotenv(env_file)
configure(log_level=log_level, log_file=log_file)
update_settings(
config,
@ -224,7 +265,7 @@ def get_free_port(port):
def print_banner(host, port):
# console = Console()
word = "LangFlow"
word = "Langflow"
colors = ["#3300cc"]
styled_word = ""

View file

@ -14,7 +14,7 @@ class Code(BaseModel):
class FrontendNodeRequest(FrontendNode):
template: dict
template: dict # type: ignore
class ValidatePromptRequest(BaseModel):

View file

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

View file

@ -21,6 +21,10 @@ async def process_graph(
# Generate result and thought
try:
if not chat_inputs.message:
logger.debug("No message provided")
raise ValueError("No message provided")
logger.debug("Generating result and thought")
result, intermediate_steps = await get_result_and_steps(
langchain_object, chat_inputs.message, websocket=websocket

View file

@ -153,6 +153,7 @@ memories:
documentation: "https://python.langchain.com/docs/modules/memory/how_to/vectorstore_retriever_memory"
MongoDBChatMessageHistory:
documentation: "https://python.langchain.com/docs/modules/memory/integrations/mongodb_chat_message_history"
prompts:
ChatMessagePromptTemplate:
documentation: "https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/msg_prompt_templates"
HumanMessagePromptTemplate:
@ -161,7 +162,6 @@ memories:
documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/how_to/prompts"
ChatPromptTemplate:
documentation: "https://python.langchain.com/docs/modules/model_io/models/chat/how_to/prompts"
prompts:
PromptTemplate:
documentation: "https://python.langchain.com/docs/modules/model_io/prompts/prompt_templates/"
textsplitters:

View file

@ -23,6 +23,7 @@ CUSTOM_NODES = {
},
"memories": {
"PostgresChatMessageHistory": frontend_node.memories.PostgresChatMessageHistoryFrontendNode(),
"MongoDBChatMessageHistory": frontend_node.memories.MongoDBChatMessageHistoryFrontendNode(),
},
"chains": {
"SeriesCharacterChain": frontend_node.chains.SeriesCharacterChainNode(),

View file

@ -2,17 +2,34 @@ from langflow.settings import settings
from sqlmodel import SQLModel, Session, create_engine
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}
else:
connect_args = {}
if not settings.database_url:
raise RuntimeError("No database_url provided")
engine = create_engine(settings.database_url, connect_args=connect_args)
def create_db_and_tables():
logger.debug("Creating database and tables")
SQLModel.metadata.create_all(engine)
logger.debug("Database and tables created")
try:
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():

View file

@ -217,7 +217,7 @@ class Vertex:
self.edges.append(edge)
def __repr__(self) -> str:
return f"Node(id={self.id}, data={self.data})"
return f"Vertex(id={self.id}, data={self.data})"
def __eq__(self, __o: object) -> bool:
return self.id == __o.id if isinstance(__o, Vertex) else False

View file

@ -127,7 +127,7 @@ def instantiate_memory(node_type, class_object, params):
# process input_key and output_key to remove them if
# they are empty strings
for key in ["input_key", "output_key"]:
if key in params and not params[key]:
if key in params and (params[key] == "" or not params[key]):
params.pop(key)
try:
@ -205,7 +205,7 @@ def instantiate_prompt(node_type, class_object, params: Dict):
prompt = class_object(**params)
format_kwargs = {}
format_kwargs: Dict[str, Any] = {}
for input_variable in prompt.input_variables:
if input_variable in params:
variable = params[input_variable]

View file

@ -66,17 +66,24 @@ def extract_input_variables_from_prompt(prompt: str) -> list[str]:
def setup_llm_caching():
"""Setup LLM caching."""
from langflow.settings import settings
try:
import langchain
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__}")
set_langchain_cache(settings)
except ImportError:
logger.warning(f"Could not import {settings.cache}. ")
except Exception as 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,15 @@
# This file is used by lc-serve to load the mounted app and serve it.
from pathlib import Path
import os
from fastapi.staticfiles import StaticFiles
# Use the JCLOUD_WORKSPACE for db URL if it's provided by JCloud.
if "JCLOUD_WORKSPACE" in os.environ:
os.environ[
"LANGFLOW_DATABASE_URL"
] = f"sqlite:///{os.environ['JCLOUD_WORKSPACE']}/langflow.db"
from langflow.main import create_app
from langflow.main import setup_app
from langflow.utils.logger import configure
app = create_app()
path = Path(__file__).parent
static_files_dir = path / "frontend"
app.mount(
"/",
StaticFiles(directory=static_files_dir, html=True),
name="static",
)
configure(log_level="DEBUG")
app = setup_app()

View file

@ -61,7 +61,7 @@ def setup_static_files(app: FastAPI, static_files_dir: Path):
# app = create_app()
# 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."""
# get the directory of the current file
if not static_files_dir:

View file

@ -1,3 +1,4 @@
from typing import Union
from langflow.api.v1.callback import (
AsyncStreamingLLMCallbackHandler,
StreamingLLMCallbackHandler,
@ -6,7 +7,7 @@ from langflow.processing.process import fix_memory_inputs, format_actions
from langflow.utils.logger import logger
async def get_result_and_steps(langchain_object, inputs: dict, **kwargs):
async def get_result_and_steps(langchain_object, inputs: Union[dict, str], **kwargs):
"""Get result and thought from extracted json"""
try:

View file

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

View file

@ -19,8 +19,7 @@ class AgentFrontendNode(FrontendNode):
if field.name in ["suffix", "prefix"]:
field.show = True
if field.name == "Tools" and name == "ZeroShotAgent":
# field.
field.type_name = "BaseTool"
field.field_type = "BaseTool"
field.is_list = True

View file

@ -33,7 +33,6 @@ class DocumentLoaderFrontNode(FrontendNode):
"SlackDirectoryLoader": build_file_field(suffixes=[".zip"], fileTypes=["zip"]),
"EverNoteLoader": build_file_field(suffixes=[".xml"], fileTypes=["xml"]),
"FacebookChatLoader": build_file_field(suffixes=[".json"], fileTypes=["json"]),
"GutenbergLoader": build_file_field(suffixes=[".txt"], fileTypes=["txt"]),
"BSHTMLLoader": build_file_field(suffixes=[".html"], fileTypes=["html"]),
"UnstructuredHTMLLoader": build_file_field(
suffixes=[".html"], fileTypes=["html"]
@ -116,8 +115,11 @@ class DocumentLoaderFrontNode(FrontendNode):
"HNLoader",
"IFixitLoader",
"IMSDbLoader",
"GutenbergLoader",
}:
name = "web_path"
elif self.template.type_name in {"GutenbergLoader"}:
name = "file_path"
elif self.template.type_name in {"GitbookLoader"}:
name = "web_page"
elif self.template.type_name in {

View file

@ -4,6 +4,10 @@ from langflow.template.field.base import TemplateField
from langflow.template.frontend_node.base import FrontendNode
from langflow.template.template.base import Template
from langchain.memory.chat_message_histories.postgres import DEFAULT_CONNECTION_STRING
from langchain.memory.chat_message_histories.mongodb import (
DEFAULT_COLLECTION_NAME,
DEFAULT_DBNAME,
)
class MemoryFrontendNode(FrontendNode):
@ -120,3 +124,56 @@ class PostgresChatMessageHistoryFrontendNode(MemoryFrontendNode):
)
description: str = "Memory store with Postgres"
base_classes: list[str] = ["PostgresChatMessageHistory", "BaseChatMessageHistory"]
class MongoDBChatMessageHistoryFrontendNode(MemoryFrontendNode):
name: str = "MongoDBChatMessageHistory"
template: Template = Template(
# langchain/memory/chat_message_histories/mongodb.py
# connection_string: str,
# session_id: str,
# database_name: str = DEFAULT_DBNAME,
# collection_name: str = DEFAULT_COLLECTION_NAME,
type_name="MongoDBChatMessageHistory",
fields=[
TemplateField(
field_type="str",
required=True,
placeholder="",
is_list=False,
show=True,
multiline=False,
name="session_id",
),
TemplateField(
field_type="str",
required=True,
show=True,
name="connection_string",
value="",
info="MongoDB connection string (e.g mongodb://mongo_user:password123@mongo:27017)",
),
TemplateField(
field_type="str",
required=True,
placeholder="",
is_list=False,
show=True,
multiline=False,
value=DEFAULT_DBNAME,
name="database_name",
),
TemplateField(
field_type="str",
required=True,
placeholder="",
is_list=False,
show=True,
multiline=False,
value=DEFAULT_COLLECTION_NAME,
name="collection_name",
),
],
)
description: str = "Memory store with MongoDB"
base_classes: list[str] = ["MongoDBChatMessageHistory", "BaseChatMessageHistory"]

View file

@ -65,6 +65,7 @@ class VectorStoreFrontendNode(FrontendNode):
show=True,
advanced=True,
multiline=False,
password=True,
value="",
)
extra_field2 = TemplateField(
@ -142,6 +143,7 @@ class VectorStoreFrontendNode(FrontendNode):
show=True,
advanced=True,
multiline=False,
password=True,
value="",
)
extra_fields.extend((extra_field, extra_field2, extra_field3, extra_field4))

View file

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

View file

@ -85,6 +85,7 @@
"daisyui": "^3.1.1",
"postcss": "^8.4.23",
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^3.2.2",
"prettier-plugin-tailwindcss": "^0.3.0",
"tailwindcss": "^3.3.2",
"typescript": "^5.0.2",
@ -146,33 +147,33 @@
}
},
"node_modules/@babel/compat-data": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.5.tgz",
"integrity": "sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.22.6.tgz",
"integrity": "sha512-29tfsWTq2Ftu7MXmimyC0C5FDZv5DYxOZkh3XD3+QW4V/BYuv/LyEsjj3c0hqedEaDt6DBfDvexMKU8YevdqFg==",
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/core": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.5.tgz",
"integrity": "sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==",
"version": "7.22.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.22.8.tgz",
"integrity": "sha512-75+KxFB4CZqYRXjx4NlR4J7yGvKumBuZTmV4NV6v09dVXXkuYVYLT68N6HCzLvfJ+fWCxQsntNzKwwIXL4bHnw==",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
"@babel/code-frame": "^7.22.5",
"@babel/generator": "^7.22.5",
"@babel/helper-compilation-targets": "^7.22.5",
"@babel/generator": "^7.22.7",
"@babel/helper-compilation-targets": "^7.22.6",
"@babel/helper-module-transforms": "^7.22.5",
"@babel/helpers": "^7.22.5",
"@babel/parser": "^7.22.5",
"@babel/helpers": "^7.22.6",
"@babel/parser": "^7.22.7",
"@babel/template": "^7.22.5",
"@babel/traverse": "^7.22.5",
"@babel/traverse": "^7.22.8",
"@babel/types": "^7.22.5",
"@nicolo-ribaudo/semver-v6": "^6.3.3",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
"json5": "^2.2.2",
"semver": "^6.3.0"
"json5": "^2.2.2"
},
"engines": {
"node": ">=6.9.0"
@ -194,9 +195,9 @@
}
},
"node_modules/@babel/generator": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.5.tgz",
"integrity": "sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==",
"version": "7.22.7",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.22.7.tgz",
"integrity": "sha512-p+jPjMG+SI8yvIaxGgeW24u7q9+5+TGpZh8/CuB7RhBKd7RCy8FayNEFNNKrNK/eUcY/4ExQqLmyrvBXKsIcwQ==",
"dependencies": {
"@babel/types": "^7.22.5",
"@jridgewell/gen-mapping": "^0.3.2",
@ -208,15 +209,15 @@
}
},
"node_modules/@babel/helper-compilation-targets": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz",
"integrity": "sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.6.tgz",
"integrity": "sha512-534sYEqWD9VfUm3IPn2SLcH4Q3P86XL+QvqdC7ZsFrzyyPF3T4XGiVghF6PTYNdWg6pXuoqXxNQAhbYeEInTzA==",
"dependencies": {
"@babel/compat-data": "^7.22.5",
"@babel/compat-data": "^7.22.6",
"@babel/helper-validator-option": "^7.22.5",
"browserslist": "^4.21.3",
"lru-cache": "^5.1.1",
"semver": "^6.3.0"
"@nicolo-ribaudo/semver-v6": "^6.3.3",
"browserslist": "^4.21.9",
"lru-cache": "^5.1.1"
},
"engines": {
"node": ">=6.9.0"
@ -297,9 +298,9 @@
}
},
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz",
"integrity": "sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
"integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
"dependencies": {
"@babel/types": "^7.22.5"
},
@ -332,12 +333,12 @@
}
},
"node_modules/@babel/helpers": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.5.tgz",
"integrity": "sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==",
"version": "7.22.6",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.22.6.tgz",
"integrity": "sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==",
"dependencies": {
"@babel/template": "^7.22.5",
"@babel/traverse": "^7.22.5",
"@babel/traverse": "^7.22.6",
"@babel/types": "^7.22.5"
},
"engines": {
@ -358,9 +359,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.5.tgz",
"integrity": "sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==",
"version": "7.22.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.22.7.tgz",
"integrity": "sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==",
"bin": {
"parser": "bin/babel-parser.js"
},
@ -404,17 +405,17 @@
}
},
"node_modules/@babel/traverse": {
"version": "7.22.5",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.5.tgz",
"integrity": "sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==",
"version": "7.22.8",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.22.8.tgz",
"integrity": "sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==",
"dependencies": {
"@babel/code-frame": "^7.22.5",
"@babel/generator": "^7.22.5",
"@babel/generator": "^7.22.7",
"@babel/helper-environment-visitor": "^7.22.5",
"@babel/helper-function-name": "^7.22.5",
"@babel/helper-hoist-variables": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.5",
"@babel/parser": "^7.22.5",
"@babel/helper-split-export-declaration": "^7.22.6",
"@babel/parser": "^7.22.7",
"@babel/types": "^7.22.5",
"debug": "^4.1.0",
"globals": "^11.1.0"
@ -1337,6 +1338,14 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/@nicolo-ribaudo/semver-v6": {
"version": "6.3.3",
"resolved": "https://registry.npmjs.org/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz",
"integrity": "sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg==",
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -2662,39 +2671,6 @@
"node": ">= 10"
}
},
"node_modules/@swc/cli/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/cli/node_modules/semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/cli/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/@swc/core": {
"version": "1.3.62",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.62.tgz",
@ -4124,14 +4100,14 @@
}
},
"node_modules/bin-version-check": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.0.0.tgz",
"integrity": "sha512-Q3FMQnS5eZmrBGqmDXLs4dbAn/f+52voP6ykJYmweSA60t6DyH4UTSwZhtbK5UH+LBoWvDljILUQMLRUtsynsA==",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz",
"integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==",
"dev": true,
"dependencies": {
"bin-version": "^6.0.0",
"semver": "^7.3.5",
"semver-truncate": "^2.0.0"
"semver": "^7.5.3",
"semver-truncate": "^3.0.0"
},
"engines": {
"node": ">=12"
@ -4140,39 +4116,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/bin-version-check/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/bin-version-check/node_modules/semver": {
"version": "7.5.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.2.tgz",
"integrity": "sha512-SoftuTROv/cRjCze/scjGyiDtcUyxw1rgYQSZY7XTmtR5hX+dm76iDbTH8TkLPHCQmlbQVSSbNZCPM2hb0knnQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/bin-version-check/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/bin-version/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
@ -4306,9 +4249,9 @@
"integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
},
"node_modules/browserslist": {
"version": "4.21.5",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.5.tgz",
"integrity": "sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==",
"version": "4.21.9",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.9.tgz",
"integrity": "sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==",
"funding": [
{
"type": "opencollective",
@ -4317,13 +4260,17 @@
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/browserslist"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"caniuse-lite": "^1.0.30001449",
"electron-to-chromium": "^1.4.284",
"node-releases": "^2.0.8",
"update-browserslist-db": "^1.0.10"
"caniuse-lite": "^1.0.30001503",
"electron-to-chromium": "^1.4.431",
"node-releases": "^2.0.12",
"update-browserslist-db": "^1.0.11"
},
"bin": {
"browserslist": "cli.js"
@ -4438,9 +4385,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001486",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001486.tgz",
"integrity": "sha512-uv7/gXuHi10Whlj0pp5q/tsK/32J2QSqVRKQhs2j8VsDCjgyruAh/eEXHF822VqO9yT6iZKw3nRwZRSPBE9OQg==",
"version": "1.0.30001513",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001513.tgz",
"integrity": "sha512-pnjGJo7SOOjAGytZZ203Em95MRM8Cr6jhCXNF/FAXTpCTRTECnqQWLpiTRqrFtdYcth8hf4WECUpkezuYsMVww==",
"funding": [
{
"type": "opencollective",
@ -8616,6 +8563,26 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/prettier-plugin-organize-imports": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/prettier-plugin-organize-imports/-/prettier-plugin-organize-imports-3.2.2.tgz",
"integrity": "sha512-e97lE6odGSiHonHJMTYC0q0iLXQyw0u5z/PJpvP/3vRy6/Zi9kLBwFAbEGjDzIowpjQv8b+J04PDamoUSQbzGA==",
"dev": true,
"peerDependencies": {
"@volar/vue-language-plugin-pug": "^1.0.4",
"@volar/vue-typescript": "^1.0.4",
"prettier": ">=2.0",
"typescript": ">=2.9"
},
"peerDependenciesMeta": {
"@volar/vue-language-plugin-pug": {
"optional": true
},
"@volar/vue-typescript": {
"optional": true
}
}
},
"node_modules/prettier-plugin-tailwindcss": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.3.0.tgz",
@ -9507,11 +9474,18 @@
}
},
"node_modules/semver": {
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"version": "7.5.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz",
"integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
},
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/semver-regex": {
@ -9527,17 +9501,38 @@
}
},
"node_modules/semver-truncate": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-2.0.0.tgz",
"integrity": "sha512-Rh266MLDYNeML5h90ttdMwfXe1+Nc4LAWd9X1KdJe8pPHP4kFmvLZALtsMNHNdvTyQygbEC0D59sIz47DIaq8w==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz",
"integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==",
"dev": true,
"dependencies": {
"semver": "^6.0.0"
"semver": "^7.3.5"
},
"engines": {
"node": ">=8"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/semver/node_modules/lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"dependencies": {
"yallist": "^4.0.0"
},
"engines": {
"node": ">=10"
}
},
"node_modules/semver/node_modules/yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
"dev": true
},
"node_modules/shadcn-ui": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/shadcn-ui/-/shadcn-ui-0.2.2.tgz",

View file

@ -106,6 +106,7 @@
"daisyui": "^3.1.1",
"postcss": "^8.4.23",
"prettier": "^2.8.8",
"prettier-plugin-organize-imports": "^3.2.2",
"prettier-plugin-tailwindcss": "^0.3.0",
"tailwindcss": "^3.3.2",
"typescript": "^5.0.2",

View file

@ -1,20 +1,19 @@
import "reactflow/dist/style.css";
import { useState, useEffect, useContext } from "react";
import "./App.css";
import { useLocation } from "react-router-dom";
import _ from "lodash";
import { useContext, useEffect, useState } from "react";
import { useLocation } from "react-router-dom";
import "reactflow/dist/style.css";
import "./App.css";
import { ErrorBoundary } from "react-error-boundary";
import ErrorAlert from "./alerts/error";
import NoticeAlert from "./alerts/notice";
import SuccessAlert from "./alerts/success";
import CrashErrorComponent from "./components/CrashErrorComponent";
import Header from "./components/headerComponent";
import { alertContext } from "./contexts/alertContext";
import { locationContext } from "./contexts/locationContext";
import { ErrorBoundary } from "react-error-boundary";
import CrashErrorComponent from "./components/CrashErrorComponent";
import { TabsContext } from "./contexts/tabsContext";
import { getVersion } from "./controllers/API";
import Router from "./routes";
import Header from "./components/headerComponent";
export default function App() {
let { setCurrent, setShowSideBar, setIsStackedOpen } =
@ -138,10 +137,7 @@ export default function App() {
<Router />
</ErrorBoundary>
<div></div>
<div
className="fixed bottom-5 left-5 flex flex-col-reverse"
style={{ zIndex: 999 }}
>
<div className="app-div" style={{ zIndex: 999 }}>
{alertsList.map((alert) => (
<div key={alert.id}>
{alert.type === "error" ? (

View file

@ -1,31 +1,30 @@
import { Info } from "lucide-react";
import React, { useContext, useEffect, useRef, useState } from "react";
import { Handle, Position, useUpdateNodeInternals } from "reactflow";
import ShadTooltip from "../../../../components/ShadTooltipComponent";
import CodeAreaComponent from "../../../../components/codeAreaComponent";
import Dropdown from "../../../../components/dropdownComponent";
import FloatComponent from "../../../../components/floatComponent";
import InputComponent from "../../../../components/inputComponent";
import InputFileComponent from "../../../../components/inputFileComponent";
import InputListComponent from "../../../../components/inputListComponent";
import IntComponent from "../../../../components/intComponent";
import PromptAreaComponent from "../../../../components/promptComponent";
import TextAreaComponent from "../../../../components/textAreaComponent";
import ToggleShadComponent from "../../../../components/toggleShadComponent";
import { PopUpContext } from "../../../../contexts/popUpContext";
import { TabsContext } from "../../../../contexts/tabsContext";
import { typesContext } from "../../../../contexts/typesContext";
import { ParameterComponentType } from "../../../../types/components";
import {
classNames,
getRandomKeyByssmm,
groupByFamily,
isValidConnection,
nodeColors,
nodeIconsLucide,
nodeNames,
} from "../../../../utils";
import { useContext, useEffect, useRef, useState } from "react";
import InputComponent from "../../../../components/inputComponent";
import InputListComponent from "../../../../components/inputListComponent";
import TextAreaComponent from "../../../../components/textAreaComponent";
import { typesContext } from "../../../../contexts/typesContext";
import { ParameterComponentType } from "../../../../types/components";
import FloatComponent from "../../../../components/floatComponent";
import Dropdown from "../../../../components/dropdownComponent";
import CodeAreaComponent from "../../../../components/codeAreaComponent";
import InputFileComponent from "../../../../components/inputFileComponent";
import { TabsContext } from "../../../../contexts/tabsContext";
import IntComponent from "../../../../components/intComponent";
import PromptAreaComponent from "../../../../components/promptComponent";
import { nodeNames } from "../../../../utils";
import React from "react";
import { nodeColors } from "../../../../utils";
import ShadTooltip from "../../../../components/ShadTooltipComponent";
import { PopUpContext } from "../../../../contexts/popUpContext";
import ToggleShadComponent from "../../../../components/toggleShadComponent";
import { Info } from "lucide-react";
export default function ParameterComponent({
left,
@ -223,7 +222,7 @@ export default function ParameterComponent({
/>
) : data.node.template[name].multiline ? (
<TextAreaComponent
disabled={disabled}
disabled={false}
value={data.node.template[name].value ?? ""}
onChange={handleOnNewValue}
/>

View file

@ -1,3 +1,15 @@
import { Zap } from "lucide-react";
import { useContext, useEffect, useRef, useState } from "react";
import { NodeToolbar } from "reactflow";
import ShadTooltip from "../../components/ShadTooltipComponent";
import Tooltip from "../../components/TooltipComponent";
import { useSSE } from "../../contexts/SSEContext";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { typesContext } from "../../contexts/typesContext";
import NodeModal from "../../modals/NodeModal";
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
import { NodeDataType } from "../../types/flow";
import {
classNames,
nodeColors,
@ -5,17 +17,6 @@ import {
toTitleCase,
} from "../../utils";
import ParameterComponent from "./components/parameterComponent";
import { typesContext } from "../../contexts/typesContext";
import { useContext, useState, useEffect, useRef } from "react";
import { NodeDataType } from "../../types/flow";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import NodeModal from "../../modals/NodeModal";
import Tooltip from "../../components/TooltipComponent";
import { NodeToolbar } from "reactflow";
import NodeToolbarComponent from "../../pages/FlowPage/components/nodeToolbarComponent";
import ShadTooltip from "../../components/ShadTooltipComponent";
import { useSSE } from "../../contexts/SSEContext";
export default function GenericNode({
data,
@ -80,30 +81,27 @@ export default function GenericNode({
<div
className={classNames(
selected ? "border border-ring" : "border",
"prompt-node relative flex w-96 flex-col justify-center rounded-lg bg-background"
"generic-node-div"
)}
>
<div className="flex w-full items-center justify-between gap-8 rounded-t-lg border-b bg-muted p-4 ">
<div className="flex w-full items-center truncate">
<div className="generic-node-div-title">
<div className="generic-node-title-arrangement">
<Icon
strokeWidth={1.5}
className="h-10 w-10 rounded p-1"
className="generic-node-icon"
style={{
color: nodeColors[types[data.type]] ?? nodeColors.unknown,
}}
/>
<div className="ml-2 flex-1 truncate">
<ShadTooltip
delayDuration={1500}
content={data.node.display_name}
>
<div className="ml-2 truncate text-primary">
<div className="generic-node-tooltip-div">
<ShadTooltip content={data.node.display_name}>
<div className="generic-node-tooltip-div text-primary">
{data.node.display_name}
</div>
</ShadTooltip>
</div>
</div>
<div className="flex gap-3">
<div className="round-button-div">
<button
className="relative"
onClick={(event) => {
@ -112,12 +110,19 @@ export default function GenericNode({
}}
></button>
</div>
<div className="flex gap-3">
<div className="round-button-div">
<div>
<Tooltip
title={
!validationStatus ? (
"Validating..."
<span className="flex">
Build{" "}
<Zap
className="mx-0.5 h-5 fill-build-trigger stroke-build-trigger stroke-1"
strokeWidth={1.5}
/>{" "}
flow to validate status.
</span>
) : (
<div className="max-h-96 overflow-auto">
{validationStatus.params
@ -129,29 +134,29 @@ export default function GenericNode({
)
}
>
<div className="relative top-[3px] h-5 w-5">
<div className="generic-node-status-position">
<div
className={classNames(
validationStatus && validationStatus.valid
? "h-4 w-4 rounded-full bg-status-green opacity-100"
: "hidden h-4 w-4 animate-spin rounded-full bg-ring opacity-0",
"absolute w-4 duration-200 ease-in-out hover:text-accent-foreground hover:transition-all"
? "green-status"
: "status-build-animation",
"status-div"
)}
></div>
<div
className={classNames(
validationStatus && !validationStatus.valid
? "h-4 w-4 rounded-full bg-status-red opacity-100"
: "hidden h-4 w-4 animate-spin rounded-full bg-ring opacity-0",
"absolute w-4 duration-200 ease-in-out hover:text-accent-foreground hover:transition-all"
? "red-status"
: "status-build-animation",
"status-div"
)}
></div>
<div
className={classNames(
!validationStatus || isBuilding
? "h-4 w-4 rounded-full bg-status-yellow opacity-100"
: "hidden h-4 w-4 animate-spin rounded-full bg-ring opacity-0",
"absolute w-4 duration-200 ease-in-out hover:text-accent-foreground hover:transition-all"
? "yellow-status"
: "status-build-animation",
"status-div"
)}
></div>
</div>
@ -160,10 +165,8 @@ export default function GenericNode({
</div>
</div>
<div className="h-full w-full py-5 text-foreground">
<div className="w-full px-5 pb-3 text-sm text-muted-foreground">
{data.node.description}
</div>
<div className="generic-node-desc">
<div className="generic-node-desc-text">{data.node.description}</div>
<>
{Object.keys(data.node.template)
@ -232,7 +235,7 @@ export default function GenericNode({
<div
className={classNames(
Object.keys(data.node.template).length < 1 ? "hidden" : "",
"flex w-full justify-center"
"flex-max-width justify-center"
)}
>
{" "}

View file

@ -1,8 +1,8 @@
import { Link } from "react-router-dom";
import { Transition } from "@headlessui/react";
import { CheckCircle2, Info, X, XCircle } from "lucide-react";
import { useState } from "react";
import { Link } from "react-router-dom";
import { SingleAlertComponentType } from "../../../../types/alerts";
import { X, CheckCircle2, Info, XCircle } from "lucide-react";
export default function SingleAlert({
dropItem,

View file

@ -1,10 +1,10 @@
import { useContext, useEffect, useRef } from "react";
import { Trash2, X } from "lucide-react";
import { useContext, useRef } from "react";
import { alertContext } from "../../contexts/alertContext";
import SingleAlert from "./components/singleAlertComponent";
import { AlertDropdownType } from "../../types/alerts";
import { PopUpContext } from "../../contexts/popUpContext";
import { AlertDropdownType } from "../../types/alerts";
import { useOnClickOutside } from "../hooks/useOnClickOutside";
import { X, Trash2 } from "lucide-react";
import SingleAlert from "./components/singleAlertComponent";
export default function AlertDropdown({}: AlertDropdownType) {
const { closePopUp } = useContext(PopUpContext);

View file

@ -1,7 +1,7 @@
import { Transition } from "@headlessui/react";
import { XCircle } from "lucide-react";
import { useEffect, useState } from "react";
import { ErrorAlertType } from "../../types/alerts";
import { XCircle } from "lucide-react";
export default function ErrorAlert({
title,
@ -39,19 +39,20 @@ export default function ErrorAlert({
removeAlert(id);
}, 500);
}}
className="mt-6 w-96 cursor-pointer rounded-md bg-error-background p-4 shadow-xl"
className="error-build-message"
>
<div className="flex">
<div className="flex-shrink-0">
<XCircle className="h-5 w-5 text-status-red" aria-hidden="true" />
<XCircle
className="error-build-message-circle"
aria-hidden="true"
/>
</div>
<div className="ml-3">
<h3 className="text-sm font-medium text-error-foreground">
{title}
</h3>
<h3 className="error-build-foreground">{title}</h3>
{list.length !== 0 ? (
<div className="mt-2 text-sm text-error-foreground">
<ul className="list-disc space-y-1 pl-5">
<div className="error-build-message-div">
<ul className="error-build-message-list">
{list.map((item, index) => (
<li key={index}>{item}</li>
))}

View file

@ -1,8 +1,8 @@
import { Transition } from "@headlessui/react";
import { Info } from "lucide-react";
import { useEffect, useState } from "react";
import { Link } from "react-router-dom";
import { NoticeAlertType } from "../../types/alerts";
import { Info } from "lucide-react";
export default function NoticeAlert({
title,

View file

@ -1,7 +1,7 @@
import { Transition } from "@headlessui/react";
import { CheckCircle2 } from "lucide-react";
import { useEffect, useState } from "react";
import { SuccessAlertType } from "../../types/alerts";
import { CheckCircle2 } from "lucide-react";
export default function SuccessAlert({
title,
@ -34,19 +34,14 @@ export default function SuccessAlert({
setShow(false);
removeAlert(id);
}}
className="mt-6 w-96 rounded-md bg-success-background p-4 shadow-xl"
className="success-alert"
>
<div className="flex">
<div className="flex-shrink-0">
<CheckCircle2
className="h-5 w-5 text-status-green"
aria-hidden="true"
/>
<CheckCircle2 className="success-alert-icon" aria-hidden="true" />
</div>
<div className="ml-3">
<p className="text-sm font-medium text-success-foreground">
{title}
</p>
<p className="success-alert-message">{title}</p>
</div>
</div>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View file

@ -1,16 +1,11 @@
import { ReactElement, useContext, useEffect, useRef, useState } from "react";
import {
AccordionComponentType,
ProgressBarType,
} from "../../types/components";
import { Progress } from "../../components/ui/progress";
import { setInterval } from "timers/promises";
import { useState } from "react";
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "../../components/ui/accordion";
import { AccordionComponentType } from "../../types/components";
export default function AccordionComponent({
trigger,

View file

@ -1,7 +1,7 @@
import React, { useState, ChangeEvent } from "react";
import { Textarea } from "../../components/ui/textarea";
import { Label } from "../../components/ui/label";
import React, { ChangeEvent, useState } from "react";
import { Input } from "../../components/ui/input";
import { Label } from "../../components/ui/label";
import { Textarea } from "../../components/ui/textarea";
type InputProps = {
name: string | null;
@ -44,12 +44,10 @@ export const EditFlowSettings: React.FC<InputProps> = ({
return (
<>
<Label>
<div className="flex justify-between">
<div className="edit-flow-arrangement">
<span className="font-medium">Name</span>{" "}
{isMaxLength && (
<span className="ml-10 animate-pulse text-status-red">
Character limit reached
</span>
<span className="edit-flow-span">Character limit reached</span>
)}
</div>
<Input

View file

@ -1,8 +1,8 @@
import { Disclosure } from "@headlessui/react";
import { useContext, useState } from "react";
import { useContext } from "react";
import { Link } from "react-router-dom";
import { classNames } from "../../utils";
import { locationContext } from "../../contexts/locationContext";
import { classNames } from "../../utils";
export default function ExtraSidebar() {
const {
@ -16,15 +16,13 @@ export default function ExtraSidebar() {
return (
<>
<aside
className={` ${
isStackedOpen ? "w-52" : "w-0 "
} flex flex-shrink-0 flex-col overflow-hidden border-r transition-all duration-500`}
className={` ${isStackedOpen ? "w-52" : "w-0 "} unused-side-bar-aside`}
>
<div className="flex h-full w-52 flex-col items-start overflow-y-auto border bg-background scrollbar-hide">
<div className="flex w-full flex-grow flex-col">
<div className="unused-side-bar-arrangement">
<div className="unused-side-bar-division">
{extraNavigation.options ? (
<div className="p-4">
<nav className="flex-1 space-y-1">
<nav className="unused-side-bar-nav">
{extraNavigation.options.map((item) =>
!item.children ? (
<div key={item.name}>
@ -32,17 +30,17 @@ export default function ExtraSidebar() {
to={item.href}
className={classNames(
item.href.split("/")[2] === current[4]
? "bg-muted text-foreground"
: "bg-background text-muted-foreground hover:bg-muted hover:text-foreground",
"group flex w-full items-center rounded-md py-2 pl-2 text-sm font-medium"
? "unused-side-bar-link-colors-true"
: "unused-side-bar-link-colors-false",
"unused-side-bar-link"
)}
>
<item.icon
className={classNames(
item.href.split("/")[2] === current[4]
? "text-ring"
: "text-ring group-hover:text-accent-foreground",
"mr-3 h-6 w-6 flex-shrink-0"
: "unused-side-bar-icon-false",
"unused-side-bar-icon"
)}
/>
{item.name}
@ -59,20 +57,22 @@ export default function ExtraSidebar() {
<Disclosure.Button
className={classNames(
item.href.split("/")[2] === current[4]
? "bg-muted text-foreground"
: "bg-background text-muted-foreground hover:bg-muted hover:text-foreground",
"group flex w-full items-center rounded-md py-2 pl-2 pr-1 text-left text-sm font-medium focus:outline-none focus:ring-1 focus:ring-ring"
? "unused-side-bar-link-colors-true"
: "unused-side-bar-link-colors-false",
"unused-side-bar-disclosure"
)}
>
<item.icon
className="mr-3 h-6 w-6 flex-shrink-0 text-ring group-hover:text-accent-foreground"
className="unused-side-bar-disclosure-icon"
aria-hidden="true"
/>
<span className="flex-1">{item.name}</span>
<svg
className={classNames(
open ? "rotate-90 text-ring" : "text-ring",
"transition-rotate ml-3 h-5 w-5 flex-shrink-0 duration-150 ease-in-out group-hover:text-accent-foreground"
open
? "unused-side-bar-svg-true"
: "text-ring",
"unused-side-bar-svg"
)}
viewBox="0 0 20 20"
aria-hidden="true"
@ -90,9 +90,9 @@ export default function ExtraSidebar() {
to={subItem.href}
className={classNames(
subItem.href.split("/")[3] === current[5]
? "bg-muted text-foreground"
: "bg-background text-muted-foreground hover:bg-muted hover:text-foreground",
"group flex w-full items-center rounded-md py-2 pl-11 pr-2 text-sm font-medium"
? "unused-side-bar-link-colors-true"
: "unused-side-bar-link-colors-false",
"unused-side-bar-disclosure-panel"
)}
>
{subItem.name}

View file

@ -1,5 +1,5 @@
import { styled } from "@mui/material/styles";
import Tooltip, { TooltipProps, tooltipClasses } from "@mui/material/Tooltip";
import { styled } from "@mui/material/styles";
export const LightTooltip = styled(({ className, ...props }: TooltipProps) => (
<Tooltip {...props} classes={{ popper: className }} />

View file

@ -1,6 +1,3 @@
import { useContext, useEffect, useRef, useState } from "react";
import { RadialProgressType } from "../../types/components";
export default function LoadingSpinner({}) {
return <></>;
}

View file

@ -1,4 +1,3 @@
import { useContext, useEffect, useRef, useState } from "react";
import { RadialProgressType } from "../../types/components";
export default function RadialProgressComponent({

View file

@ -1,4 +1,4 @@
import { RadialProgressType, ShadToolTipType } from "../../types/components";
import { ShadToolTipType } from "../../types/components";
import {
Tooltip,
TooltipContent,
@ -11,14 +11,20 @@ export default function ShadTooltip({
side,
asChild = true,
children,
delayDuration,
style,
delayDuration = 500,
}: ShadToolTipType) {
return (
<TooltipProvider>
<Tooltip delayDuration={delayDuration}>
<TooltipTrigger asChild={asChild}>{children}</TooltipTrigger>
<TooltipContent side={side} avoidCollisions={false} sticky="always">
<TooltipContent
className={style}
side={side}
avoidCollisions={false}
sticky="always"
>
{content}
</TooltipContent>
</Tooltip>

View file

@ -1,6 +1,5 @@
import { ReactElement } from "react";
import { LightTooltip } from "../LightTooltipComponent";
import { TooltipComponentType } from "../../types/components";
import { LightTooltip } from "../LightTooltipComponent";
export default function Tooltip({
children,

View file

@ -1,26 +1,15 @@
import { Trash2, ExternalLink } from "lucide-react";
import { Trash2 } from "lucide-react";
import { useContext } from "react";
import { Link } from "react-router-dom";
import { TabsContext } from "../../contexts/tabsContext";
import { FlowType } from "../../types/flow";
import { gradients } from "../../utils";
import {
CardTitle,
Card,
CardDescription,
CardFooter,
Card,
CardHeader,
CardTitle,
} from "../ui/card";
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../ui/dialog";
import { Button } from "@mui/material";
export const CardComponent = ({
flow,
@ -38,42 +27,22 @@ export const CardComponent = ({
return (
<Card className="group">
<CardHeader>
<CardTitle className="flex w-full items-center gap-4">
<CardTitle className="card-component-title-display">
<span
className={
"flex h-7 w-7 items-center justify-center rounded-full text-2xl " +
"card-component-image " +
gradients[parseInt(flow.id.slice(0, 12), 16) % gradients.length]
}
></span>
<span className="inline-block w-full flex-1 break-words truncate-doubleline">
{flow.name}
</span>
<span className="card-component-title-size">{flow.name}</span>
{onDelete && (
<Dialog>
<DialogTrigger asChild>
<button className="flex self-start">
<Trash2 className="h-4 w-4 text-primary opacity-0 transition-all group-hover:opacity-100" />
</button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you sure absolutely sure?</DialogTitle>
<DialogDescription>
This action cannot be undone. Are you sure you want to
permanently delete this file from our servers?
</DialogDescription>
</DialogHeader>
<DialogFooter>
<Button type="submit" onClick={onDelete}>
Confirm
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
<button className="card-component-delete-button" onClick={onDelete}>
<Trash2 className="card-component-delete-icon" />
</button>
)}
</CardTitle>
<CardDescription className="pb-2 pt-2">
<div className="truncate-doubleline">
<CardDescription className="card-component-desc">
<div className="card-component-desc-text">
{flow.description}
{/* {flow.description} */}
</div>
@ -81,8 +50,8 @@ export const CardComponent = ({
</CardHeader>
<CardFooter>
<div className="flex w-full items-end justify-between gap-2">
<div className="flex flex-wrap gap-2">
<div className="card-component-footer-arrangement">
<div className="card-component-footer">
{/* <Badge variant="secondary">Agent</Badge>
<Badge variant="secondary">
<div className="w-3">

View file

@ -1,16 +1,16 @@
import { useContext, useState } from "react";
import { Transition } from "@headlessui/react";
import { Zap } from "lucide-react";
import { validateNodes } from "../../../utils";
import { FlowType } from "../../../types/flow";
import { useContext, useState } from "react";
import Loading from "../../../components/ui/loading";
import { useSSE } from "../../../contexts/SSEContext";
import { typesContext } from "../../../contexts/typesContext";
import { alertContext } from "../../../contexts/alertContext";
import { typesContext } from "../../../contexts/typesContext";
import { postBuildInit } from "../../../controllers/API";
import { FlowType } from "../../../types/flow";
import { validateNodes } from "../../../utils";
import RadialProgressComponent from "../../RadialProgress";
import { TabsContext } from "../../../contexts/tabsContext";
import RadialProgressComponent from "../../RadialProgress";
export default function BuildTrigger({
open,
@ -168,7 +168,7 @@ export default function BuildTrigger({
>
<div className="fixed bottom-20 right-4">
<div
className={`${eventClick} align-center shadow-round-btn-shadow hover:shadow-round-btn-shadow flex h-12 w-12 cursor-pointer justify-center rounded-full bg-border px-3 py-1 shadow-md`}
className={`${eventClick} round-button-form`}
onClick={() => {
handleBuild(flow);
}}
@ -176,7 +176,7 @@ export default function BuildTrigger({
onMouseLeave={handleMouseLeave}
>
<button>
<div className="flex items-center gap-3">
<div className="round-button-div">
{isBuilding && progress < 1 ? (
// Render your loading animation here when isBuilding is true
<RadialProgressComponent
@ -185,7 +185,10 @@ export default function BuildTrigger({
value={progress}
></RadialProgressComponent>
) : isBuilding ? (
<Loading strokeWidth={1.5} className="stroke-build-trigger" />
<Loading
strokeWidth={1.5}
className="build-trigger-loading-icon"
/>
) : (
<Zap
strokeWidth={1.5}

View file

@ -1,55 +0,0 @@
import { useState } from "react";
import { ChatMessageType } from "../../../types/chat";
import { nodeColors } from "../../../utils";
import Convert from "ansi-to-html";
import { MessageCircle } from "lucide-react";
import DOMPurify from "dompurify";
const convert = new Convert({ newline: true });
export default function ChatMessage({ chat }: { chat: ChatMessageType }) {
const [hidden, setHidden] = useState(true);
return (
<div>
{!chat.isSend ? (
<div className="w-full text-start">
<div
style={{ backgroundColor: nodeColors["chat"] }}
className=" relative inline-block w-fit max-w-[280px] overflow-hidden rounded-xl rounded-tl-none text-start text-sm font-normal text-background"
>
{hidden && chat.thought && chat.thought !== "" && (
<div
onClick={() => setHidden((prev) => !prev)}
className="absolute right-2 top-2 cursor-pointer"
>
<MessageCircle className="h-5 w-5 animate-bounce" />
</div>
)}
{chat.thought && chat.thought !== "" && !hidden && (
<div
onClick={() => setHidden((prev) => !prev)}
style={{ backgroundColor: nodeColors["thought"] }}
className=" inline-block w-full cursor-pointer px-5 pb-3 pt-3 text-start"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(convert.toHtml(chat.thought)),
}}
></div>
)}
{chat.thought && chat.thought !== "" && !hidden && <br></br>}
<div
className="w-full rounded-b-md px-4 pb-3 pr-8 pt-3"
style={{ backgroundColor: nodeColors["chat"] }}
>
{chat.message}
</div>
</div>
</div>
) : (
<div className="w-full text-end">
<div className="inline-block w-fit max-w-[280px] overflow-hidden rounded-xl rounded-tr-none bg-input p-3 px-5 text-start text-sm font-normal text-black">
{chat.message}
</div>
</div>
)}
</div>
);
}

View file

@ -1,7 +1,6 @@
import { Transition } from "@headlessui/react";
import { MessagesSquare } from "lucide-react";
import { alertContext } from "../../../contexts/alertContext";
import { useContext } from "react";
import {
CHAT_CANNOT_OPEN_DESCRIPTION,
@ -9,6 +8,7 @@ import {
FLOW_NOT_BUILT_DESCRIPTION,
FLOW_NOT_BUILT_TITLE,
} from "../../../constants";
import { alertContext } from "../../../contexts/alertContext";
export default function ChatTrigger({ open, setOpen, isBuilt, canOpen }) {
const { setErrorData } = useContext(alertContext);
@ -45,7 +45,7 @@ export default function ChatTrigger({ open, setOpen, isBuilt, canOpen }) {
<button
onClick={handleClick}
className={
"shadow-round-btn-shadow hover:shadow-round-btn-shadow fixed bottom-4 right-4 flex h-12 w-12 items-center justify-center rounded-full bg-border px-3 py-1 shadow-md transition-all " +
"shadow-round-btn-shadow hover:shadow-round-btn-shadow message-button " +
(!isBuilt || !canOpen ? "cursor-not-allowed" : "cursor-pointer")
}
>
@ -54,8 +54,8 @@ export default function ChatTrigger({ open, setOpen, isBuilt, canOpen }) {
className={
"h-6 w-6 transition-all " +
(isBuilt && canOpen
? "fill-chat-trigger stroke-chat-trigger stroke-1"
: "fill-chat-trigger-disabled stroke-chat-trigger-disabled stroke-1")
? "message-button-icon"
: "disabled-message-button-icon")
}
style={{ color: "white" }}
strokeWidth={1.5}

View file

@ -1,14 +1,14 @@
import { useContext, useEffect, useRef, useState } from "react";
import { useNodes } from "reactflow";
import { ChatType } from "../../types/chat";
import ChatTrigger from "./chatTrigger";
import BuildTrigger from "./buildTrigger";
import ChatTrigger from "./chatTrigger";
import { getBuildStatus } from "../../controllers/API";
import { NodeType } from "../../types/flow";
import FormModal from "../../modals/formModal";
import { TabsContext } from "../../contexts/tabsContext";
import * as _ from "lodash";
import { TabsContext } from "../../contexts/tabsContext";
import { getBuildStatus } from "../../controllers/API";
import FormModal from "../../modals/formModal";
import { NodeType } from "../../types/flow";
export default function Chat({ flow }: ChatType) {
const [open, setOpen] = useState(false);

View file

@ -1,10 +1,9 @@
import { Listbox, Transition } from "@headlessui/react";
import { Check, ChevronsUpDown } from "lucide-react";
import { Fragment, useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { DropDownComponentType } from "../../types/components";
import { classNames } from "../../utils";
import { ChevronsUpDown, Check } from "lucide-react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
export default function Dropdown({
value,
@ -39,20 +38,16 @@ export default function Dropdown({
<Listbox.Button
className={
editNode
? "border-1 input-edit-node relative pr-8"
: "input-primary py-2 pl-3 pr-10 text-left"
? "dropdown-component-outline"
: "dropdown-component-false-outline"
}
>
<span className="block w-full truncate bg-background">
<span className="dropdown-component-display">
{internalValue}
</span>
<span
className={
"pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2"
}
>
<span className={"dropdown-component-arrow"}>
<ChevronsUpDown
className="h-5 w-5 text-muted-foreground"
className="dropdown-component-arrow-color"
aria-hidden="true"
/>
</span>
@ -68,8 +63,8 @@ export default function Dropdown({
<Listbox.Options
className={classNames(
editNode
? "z-10 mt-1 max-h-60 w-[215px] overflow-auto rounded-md bg-background py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm"
: "nowheel overflow-y z-10 mt-1 max-h-60 w-full overflow-auto rounded-md bg-background py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm ",
? "dropdown-component-true-options nowheel"
: "dropdown-component-false-options nowheel",
apiModal ? "mb-2 w-[250px]" : "absolute"
)}
>
@ -80,8 +75,8 @@ export default function Dropdown({
classNames(
active ? " bg-accent" : "",
editNode
? "relative cursor-default select-none py-0.5 pl-3 pr-12"
: "relative cursor-default select-none py-2 pl-3 pr-9"
? "dropdown-component-false-option"
: "dropdown-component-true-option"
)
}
value={option}
@ -101,14 +96,14 @@ export default function Dropdown({
<span
className={classNames(
active ? "text-background " : "",
"absolute inset-y-0 right-0 flex items-center pr-4"
"dropdown-component-choosal"
)}
>
<Check
className={
active
? "h-5 w-5 text-black"
: "h-5 w-5 text-black"
? "dropdown-component-check-icon"
: "dropdown-component-check-icon"
}
aria-hidden="true"
/>

View file

@ -1,7 +1,7 @@
import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { FloatComponentType } from "../../types/components";
export default function FloatComponent({
value,
@ -30,11 +30,7 @@ export default function FloatComponent({
}, [closePopUp]);
return (
<div
className={
"w-full " + (disabled ? "pointer-events-none cursor-not-allowed" : "")
}
>
<div className={"w-full " + (disabled ? "float-component-pointer" : "")}>
<input
onFocus={() => {
if (disableCopyPaste) setDisableCopyPaste(true);

View file

@ -1,27 +1,25 @@
import { useContext } from "react";
import { TabsContext } from "../../../../contexts/tabsContext";
import { PopUpContext } from "../../../../contexts/popUpContext";
import {
Plus,
ChevronDown,
ChevronLeft,
Undo,
Plus,
Redo,
Settings2,
Undo,
} from "lucide-react";
import { useContext } from "react";
import { PopUpContext } from "../../../../contexts/popUpContext";
import { TabsContext } from "../../../../contexts/tabsContext";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../../../ui/dropdown-menu";
import { alertContext } from "../../../../contexts/alertContext";
import { Link, useNavigate } from "react-router-dom";
import { alertContext } from "../../../../contexts/alertContext";
import { undoRedoContext } from "../../../../contexts/undoRedoContext";
import FlowSettingsModal from "../../../../modals/flowSettingsModal";
import { Button } from "../../../ui/button";
@ -47,19 +45,19 @@ export const MenuBar = ({ flows, tabId }) => {
let current_flow = flows.find((flow) => flow.id === tabId);
return (
<div className="flex items-center gap-2">
<div className="round-button-div">
<Link to="/">
<ChevronLeft className="w-4" />
</Link>
<div className="flex items-center gap-0.5 rounded-md px-1.5 py-1 text-sm font-medium">
<div className="header-menu-bar">
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
className="flex max-w-[200px] items-center gap-2"
className="header-menu-bar-display"
variant="primary"
size="sm"
>
<div className="flex-1 truncate">{current_flow.name}</div>
<div className="header-menu-flow-name">{current_flow.name}</div>
<ChevronDown className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
@ -71,7 +69,7 @@ export const MenuBar = ({ flows, tabId }) => {
}}
className="cursor-pointer"
>
<Plus className="mr-2 h-4 w-4" />
<Plus className="header-menu-options" />
New
</DropdownMenuItem>
<DropdownMenuItem
@ -80,7 +78,7 @@ export const MenuBar = ({ flows, tabId }) => {
}}
className="cursor-pointer"
>
<Settings2 className="mr-2 h-4 w-4 " />
<Settings2 className="header-menu-options " />
Settings
</DropdownMenuItem>
<DropdownMenuItem
@ -89,7 +87,7 @@ export const MenuBar = ({ flows, tabId }) => {
}}
className="cursor-pointer"
>
<Undo className="mr-2 h-4 w-4 " />
<Undo className="header-menu-options " />
Undo
</DropdownMenuItem>
<DropdownMenuItem
@ -98,7 +96,7 @@ export const MenuBar = ({ flows, tabId }) => {
}}
className="cursor-pointer"
>
<Redo className="mr-2 h-4 w-4 " />
<Redo className="header-menu-options " />
Redo
</DropdownMenuItem>
<DropdownMenuSeparator />

View file

@ -1,19 +1,18 @@
import { BellIcon, Home, MoonIcon, SunIcon, Users2 } from "lucide-react";
import { Bell, Home, MoonIcon, SunIcon, Users2 } from "lucide-react";
import { useContext, useEffect, useState } from "react";
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa";
import { Button } from "../ui/button";
import { TabsContext } from "../../contexts/tabsContext";
import { Link, useLocation, useParams } from "react-router-dom";
import AlertDropdown from "../../alerts/alertDropDown";
import { USER_PROJECTS_HEADER } from "../../constants";
import { alertContext } from "../../contexts/alertContext";
import { darkContext } from "../../contexts/darkContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { typesContext } from "../../contexts/typesContext";
import MenuBar from "./components/menuBar";
import { Link, useLocation, useParams } from "react-router-dom";
import { USER_PROJECTS_HEADER } from "../../constants";
import { getRepoStars } from "../../controllers/API";
import { Button } from "../ui/button";
import { Separator } from "../ui/separator";
import { Bell } from "lucide-react";
import MenuBar from "./components/menuBar";
export default function Header() {
const { flows, addFlow, tabId } = useContext(TabsContext);
@ -36,8 +35,8 @@ export default function Header() {
fetchStars();
}, []);
return (
<div className="flex h-12 w-full items-center justify-between border-b bg-muted">
<div className="flex w-96 items-center justify-start gap-2">
<div className="header-arrangement">
<div className="header-start-display">
<Link to="/">
<span className="ml-4 text-2xl"></span>
</Link>
@ -45,7 +44,7 @@ export default function Header() {
<MenuBar flows={flows} tabId={tabId} />
)}
</div>
<div className="flex items-center gap-2">
<div className="round-button-div">
<Link to="/">
<Button
className="gap-2"
@ -69,19 +68,17 @@ export default function Header() {
</Button>
</Link>
</div>
<div className="flex w-96 justify-end px-2">
<div className="ml-auto mr-2 flex items-center gap-5">
<div className="header-end-division">
<div className="header-end-display">
<a
href="https://github.com/logspace-ai/langflow"
target="_blank"
rel="noreferrer"
className="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"
className="header-github-link"
>
<FaGithub className="mr-2 h-5 w-5" />
Star
<div className="-mr-px ml-2 flex h-9 items-center justify-center rounded-md rounded-l-none border bg-background px-2 text-sm">
{stars}
</div>
<div className="header-github-display">{stars}</div>
</a>
<a
href="https://twitter.com/logspace_ai"
@ -89,7 +86,7 @@ export default function Header() {
rel="noreferrer"
className="text-muted-foreground"
>
<FaTwitter className="h-5 w-5 hover:text-accent-foreground" />
<FaTwitter className="side-bar-button-size" />
</a>
<a
href="https://discord.gg/EqksyE2EX9"
@ -97,24 +94,24 @@ export default function Header() {
rel="noreferrer"
className="text-muted-foreground"
>
<FaDiscord className="h-5 w-5 hover:text-accent-foreground" />
<FaDiscord className="side-bar-button-size" />
</a>
<Separator orientation="vertical" />
<button
className="text-muted-foreground hover:text-accent-foreground "
className="extra-side-bar-save-disable"
onClick={() => {
setDark(!dark);
}}
>
{dark ? (
<SunIcon className="h-5 w-5" />
<SunIcon className="side-bar-button-size" />
) : (
<MoonIcon className="h-5 w-5" />
<MoonIcon className="side-bar-button-size" />
)}
</button>
<button
className="relative text-muted-foreground hover:text-accent-foreground"
className="extra-side-bar-save-disable relative"
onClick={(event: React.MouseEvent<HTMLElement>) => {
setNotificationCenter(false);
const { top, left } = (
@ -128,15 +125,13 @@ export default function Header() {
>
<AlertDropdown />
</div>
<div className="fixed left-0 top-0 h-screen w-screen"></div>
<div className="header-notifications-box"></div>
</>
);
}}
>
{notificationCenter && (
<div className="absolute right-[3px] h-1.5 w-1.5 rounded-full bg-destructive"></div>
)}
<Bell className="h-5 w-5" aria-hidden="true" />
{notificationCenter && <div className="header-notifications"></div>}
<Bell className="side-bar-button-size" aria-hidden="true" />
</button>
</div>
</div>

View file

@ -1,8 +1,8 @@
import { useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { InputComponentType } from "../../types/components";
import { classNames } from "../../utils";
import { TabsContext } from "../../contexts/tabsContext";
import { PopUpContext } from "../../contexts/popUpContext";
export default function InputComponent({
value,
@ -29,13 +29,7 @@ export default function InputComponent({
}, [closePopUp]);
return (
<div
className={
disabled
? "pointer-events-none relative cursor-not-allowed"
: "relative"
}
>
<div className={disabled ? "input-component-div" : "relative"}>
<input
value={myValue}
onFocus={() => {
@ -45,7 +39,7 @@ export default function InputComponent({
if (disableCopyPaste) setDisableCopyPaste(false);
}}
className={classNames(
" pr-12 ",
" pr-9 ",
disabled ? " input-disable " : "",
password && !pwdVisible && myValue !== "" ? "password" : "",
editNode ? " input-edit-node " : " input-primary ",
@ -61,8 +55,8 @@ export default function InputComponent({
<button
className={classNames(
editNode
? "absolute inset-y-0 right-0 items-center pr-2 text-muted-foreground"
: "absolute inset-y-0 right-0 items-center px-4 text-muted-foreground"
? "input-component-true-button"
: "input-component-false-button"
)}
onClick={() => {
setPwdVisible(!pwdVisible);
@ -78,8 +72,8 @@ export default function InputComponent({
stroke="currentColor"
className={classNames(
editNode
? "absolute bottom-0.5 right-2 h-5 w-5"
: "absolute bottom-2 right-3 h-5 w-5"
? "input-component-true-svg"
: "input-component-false-svg"
)}
>
<path
@ -97,8 +91,8 @@ export default function InputComponent({
stroke="currentColor"
className={classNames(
editNode
? "absolute bottom-0.5 right-2 h-5 w-5"
: "absolute bottom-2 right-3 h-5 w-5"
? "input-component-true-svg"
: "input-component-false-svg"
)}
>
<path

View file

@ -1,9 +1,9 @@
import { FileSearch2 } from "lucide-react";
import { useContext, useEffect, useState } from "react";
import { alertContext } from "../../contexts/alertContext";
import { FileComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
import { FileSearch2 } from "lucide-react";
import { uploadFile } from "../../controllers/API";
import { FileComponentType } from "../../types/components";
export default function InputFileComponent({
value,
@ -91,19 +91,18 @@ export default function InputFileComponent({
input.click();
};
return (
<div
className={
disabled ? "pointer-events-none w-full cursor-not-allowed" : "w-full"
}
>
<div className="flex w-full items-center">
<div className={disabled ? "input-component-div" : "w-full"}>
<div className="input-file-component">
<span
onClick={handleButtonClick}
className={
editNode
? "input-edit-node " + "input-primary "
: "input-primary " + (disabled ? "input-disable " : "")
? " input-edit-node " + " input-dialog "
: (disabled ? " input-disable " : "") +
" input-primary " +
" input-dialog "
}
>
{myValue !== "" ? myValue : "No file"}
@ -112,7 +111,10 @@ export default function InputFileComponent({
{!editNode && !loading && (
<FileSearch2
strokeWidth={1.5}
className="h-6 w-6 hover:text-accent-foreground"
className={
"icons-parameters-comp" +
(disabled ? " text-ring " : " hover:text-accent-foreground")
}
/>
)}
{!editNode && loading && (

View file

@ -1,9 +1,8 @@
import { useContext, useEffect, useState } from "react";
import { InputListComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
import _ from "lodash";
import { X, Plus } from "lucide-react";
import { Plus, X } from "lucide-react";
import { PopUpContext } from "../../contexts/popUpContext";
export default function InputListComponent({

View file

@ -1,8 +1,7 @@
import { useContext, useEffect, useState } from "react";
import { FloatComponentType } from "../../types/components";
import { TabsContext } from "../../contexts/tabsContext";
import { classNames } from "../../utils";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { FloatComponentType } from "../../types/components";
export default function IntComponent({
value,

View file

@ -1,13 +1,13 @@
import { useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TextAreaComponentType } from "../../types/components";
import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components";
import { TypeModal } from "../../utils";
import { ExternalLink } from "lucide-react";
import { postValidatePrompt } from "../../controllers/API";
import { typesContext } from "../../contexts/typesContext";
import * as _ from "lodash";
import { ExternalLink } from "lucide-react";
import { typesContext } from "../../contexts/typesContext";
import { postValidatePrompt } from "../../controllers/API";
export default function PromptAreaComponent({
field_name,
@ -100,7 +100,7 @@ export default function PromptAreaComponent({
<ExternalLink
strokeWidth={1.5}
className={
"ml-3 h-6 w-6" +
"icons-parameters-comp" +
(disabled ? " text-ring" : " hover:text-accent-foreground")
}
/>

View file

@ -1,7 +1,7 @@
import { useContext, useEffect, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { TextAreaComponentType } from "../../types/components";
import GenericModal from "../../modals/genericModal";
import { TextAreaComponentType } from "../../types/components";
import { TypeModal } from "../../utils";
import { ExternalLink } from "lucide-react";
@ -30,34 +30,23 @@ export default function TextAreaComponent({
<div className={disabled ? "cursor-not-allowed" : ""}>
<div
className={
(editNode ? "w-full items-center" : "flex w-full items-center") +
(editNode ? "relative top-2 w-full" : "flex w-full items-center") +
(disabled ? " pointer-events-none" : "")
}
>
<span
onClick={() => {
openPopUp(
<GenericModal
type={TypeModal.TEXT}
buttonText="Finishing Editing"
modalTitle="Edit Text"
value={myValue}
setValue={(t: string) => {
setMyValue(t);
onChange(t);
}}
/>
);
}}
<input
value={myValue}
className={
editNode
? "input-edit-node input-dialog "
: "input-dialog input-primary " +
(disabled ? "input-disable" : "")
? "input-edit-node"
: "input-primary" + (disabled ? " input-disable " : "")
}
>
{myValue !== "" ? myValue : "Type something..."}
</span>
placeholder={"Type something..."}
onChange={(e) => {
setMyValue(e.target.value);
onChange(e.target.value);
}}
/>
<button
onClick={() => {
@ -79,7 +68,7 @@ export default function TextAreaComponent({
<ExternalLink
strokeWidth={1.5}
className={
"ml-3 h-6 w-6" +
"icons-parameters-comp" +
(disabled ? " text-ring" : " hover:text-accent-foreground")
}
/>

View file

@ -1,7 +1,7 @@
import { Switch } from "@headlessui/react";
import { classNames } from "../../utils";
import { useEffect } from "react";
import { ToggleComponentType } from "../../types/components";
import { classNames } from "../../utils";
export default function ToggleComponent({
enabled,
@ -22,14 +22,14 @@ export default function ToggleComponent({
}}
className={classNames(
enabled ? "bg-primary" : "bg-input",
"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-1 focus:ring-primary focus:ring-offset-1"
"toggle-component-switch "
)}
>
<span className="sr-only">Use setting</span>
<span
className={classNames(
enabled ? "translate-x-5" : "translate-x-0",
"pointer-events-none relative inline-block h-5 w-5 transform rounded-full shadow ring-0 transition duration-200 ease-in-out",
"toggle-component-span",
disabled ? "bg-input " : "bg-background"
)}
>
@ -38,7 +38,7 @@ export default function ToggleComponent({
enabled
? "opacity-0 duration-100 ease-out"
: "opacity-100 duration-200 ease-in",
"absolute inset-0 flex h-full w-full items-center justify-center transition-opacity"
"toggle-component-second-span"
)}
aria-hidden="true"
></span>
@ -47,7 +47,7 @@ export default function ToggleComponent({
enabled
? "opacity-100 duration-200 ease-in"
: "opacity-0 duration-100 ease-out",
"absolute inset-0 flex h-full w-full items-center justify-center transition-opacity"
"toggle-component-second-span"
)}
aria-hidden="true"
></span>

View file

@ -1,4 +1,3 @@
import { useEffect } from "react";
import { ToggleComponentType } from "../../types/components";
import { Switch } from "../ui/switch";

View file

@ -1,8 +1,8 @@
"use client";
import * as React from "react";
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { ChevronDownIcon } from "@radix-ui/react-icons";
import * as React from "react";
import { cn } from "../../utils";
const Accordion = AccordionPrimitive.Root;

View file

@ -1,5 +1,5 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "../../utils";
const badgeVariants = cva(

View file

@ -1,6 +1,6 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "../../utils";
const buttonVariants = cva(

View file

@ -1,8 +1,8 @@
"use client";
import * as React from "react";
import * as CheckboxPrimitive from "@radix-ui/react-checkbox";
import { Check } from "lucide-react";
import * as React from "react";
import { cn } from "../../utils";
const Checkbox = React.forwardRef<

View file

@ -1,6 +1,6 @@
import * as React from "react";
import * as DialogPrimitive from "@radix-ui/react-dialog";
import { X } from "lucide-react";
import * as React from "react";
import { cn } from "../../utils";
const Dialog = DialogPrimitive.Root;

View file

@ -1,8 +1,8 @@
"use client";
import * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
import { cn } from "../../utils";
const DropdownMenu = DropdownMenuPrimitive.Root;

View file

@ -1,8 +1,8 @@
"use client";
import * as React from "react";
import * as LabelPrimitive from "@radix-ui/react-label";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "../../utils";
const labelVariants = cva(

View file

@ -1,8 +1,8 @@
"use client";
import * as React from "react";
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { Check, ChevronRight, Circle } from "lucide-react";
import * as React from "react";
import { cn } from "../../utils";

View file

@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import * as ProgressPrimitive from "@radix-ui/react-progress";
import * as React from "react";
import { cn } from "../../utils";
const Progress = React.forwardRef<

View file

@ -1,4 +1,4 @@
import { useState, useEffect, useRef } from "react";
import { useEffect, useRef, useState } from "react";
import { cn } from "../../utils";
export default function RenameLabel(props) {

View file

@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import * as SeparatorPrimitive from "@radix-ui/react-separator";
import * as React from "react";
import { cn } from "../../utils";
const Separator = React.forwardRef<

View file

@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as React from "react";
import { cn } from "../../utils";
const Switch = React.forwardRef<

View file

@ -5,7 +5,7 @@ const Table = React.forwardRef<
HTMLTableElement,
React.HTMLAttributes<HTMLTableElement>
>(({ className, ...props }, ref) => (
<div className="w-full overflow-auto">
<div className="">
<table
ref={ref}
className={cn("w-full caption-bottom text-sm", className)}

View file

@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import * as TabsPrimitive from "@radix-ui/react-tabs";
import * as React from "react";
import { cn } from "../../utils";
const Tabs = TabsPrimitive.Root;

View file

@ -1,7 +1,7 @@
"use client";
import * as React from "react";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
import * as React from "react";
import { cn } from "../../utils";
const TooltipProvider = TooltipPrimitive.Provider;

View file

@ -1,7 +1,9 @@
// src/constants.tsx
import { MessageSquare } from "lucide-react";
import { FlowType } from "./types/flow";
import { buildTweaks } from "./utils";
import { TabsState } from "./types/tabs";
import { buildInputs, buildTweaks } from "./utils";
/**
* The base text for subtitle of Export Dialog (Toolbar)
@ -56,6 +58,8 @@ export const CHAT_CANNOT_OPEN_DESCRIPTION = "This is not a chat flow.";
export const FLOW_NOT_BUILT_TITLE = "Flow not built";
export const THOUGHTS_ICON = MessageSquare;
export const FLOW_NOT_BUILT_DESCRIPTION =
"Please build the flow before chatting.";
@ -70,7 +74,11 @@ export const TEXT_DIALOG_SUBTITLE = "Edit your text.";
* @param {string} flowId - The id of the flow
* @returns {string} - The python code
*/
export const getPythonApiCode = (flow: FlowType, tweak?): string => {
export const getPythonApiCode = (
flow: FlowType,
tweak?: any[],
tabsState?: TabsState
): string => {
const flowId = flow.id;
// create a dictionary of node ids and the values is an empty dictionary
@ -78,7 +86,9 @@ export const getPythonApiCode = (flow: FlowType, tweak?): string => {
// node.data.id
// }
const tweaks = buildTweaks(flow);
const inputs = buildInputs(tabsState, flow.id);
return `import requests
from typing import Optional
BASE_API_URL = "${window.location.protocol}//${
window.location.host
@ -92,7 +102,7 @@ TWEAKS = ${
: JSON.stringify(tweaks, null, 2)
}
def run_flow(message: str, flow_id: str, tweaks: dict = None) -> dict:
def run_flow(inputs: dict, flow_id: str, tweaks: Optional[dict] = None) -> dict:
"""
Run a flow with a given message and optional tweaks.
@ -103,7 +113,7 @@ def run_flow(message: str, flow_id: str, tweaks: dict = None) -> dict:
"""
api_url = f"{BASE_API_URL}/{flow_id}"
payload = {"inputs": {"input": message}}
payload = {"inputs": inputs}
if tweaks:
payload["tweaks"] = tweaks
@ -112,23 +122,29 @@ def run_flow(message: str, flow_id: str, tweaks: dict = None) -> dict:
return response.json()
# Setup any tweaks you want to apply to the flow
print(run_flow("Your message", flow_id=FLOW_ID, tweaks=TWEAKS))`;
inputs = ${inputs}
print(run_flow(inputs, flow_id=FLOW_ID, tweaks=TWEAKS))`;
};
/**
* Function to get the curl code for the API
* @param {string} flowId - The id of the flow
* @returns {string} - The curl code
*/
export const getCurlCode = (flow: FlowType, tweak?): string => {
export const getCurlCode = (
flow: FlowType,
tweak?: any[],
tabsState?: TabsState
): string => {
const flowId = flow.id;
const tweaks = buildTweaks(flow);
const inputs = buildInputs(tabsState, flow.id);
return `curl -X POST \\
${window.location.protocol}//${
window.location.host
}/api/v1/process/${flowId} \\
-H 'Content-Type: application/json' \\
-d '{"inputs": {"input": message}, "tweaks": ${
-d '{"inputs": ${inputs}, "tweaks": ${
tweak && tweak.length > 0
? buildTweakObject(tweak)
: JSON.stringify(tweaks, null, 2)
@ -139,9 +155,14 @@ export const getCurlCode = (flow: FlowType, tweak?): string => {
* @param {string} flowName - The name of the flow
* @returns {string} - The python code
*/
export const getPythonCode = (flow: FlowType, tweak?): string => {
export const getPythonCode = (
flow: FlowType,
tweak?: any[],
tabsState?: TabsState
): string => {
const flowName = flow.name;
const tweaks = buildTweaks(flow);
const inputs = buildInputs(tabsState, flow.id);
return `from langflow import load_flow_from_json
TWEAKS = ${
tweak && tweak.length > 0
@ -150,7 +171,8 @@ TWEAKS = ${
}
flow = load_flow_from_json("${flowName}.json", tweaks=TWEAKS)
# Now you can use it like any chain
flow("Hey, have you heard of LangFlow?")`;
inputs = ${inputs}
flow(inputs)`;
};
function buildTweakObject(tweak) {
@ -529,4 +551,4 @@ export const USER_PROJECTS_HEADER = "My Collection";
*
*/
export const HIGHLIGH_CSS =
"block pl-3 pr-14 py-2 w-full h-full text-sm outline-0 border-0 break-all";
"block pl-3 pr-14 py-2 w-full h-full text-sm outline-0 border-0 break-all overflow-y-hidden max-w-[75vw]";

View file

@ -1,10 +1,4 @@
import {
createContext,
useContext,
useState,
useEffect,
useCallback,
} from "react";
import { createContext, useCallback, useContext, useState } from "react";
const initialValue = {
updateSSEData: ({}) => {},

View file

@ -1,13 +1,13 @@
import { ReactNode } from "react";
import { ReactFlowProvider } from "reactflow";
import { SSEProvider } from "./SSEContext";
import { AlertProvider } from "./alertContext";
import { DarkProvider } from "./darkContext";
import { LocationProvider } from "./locationContext";
import PopUpProvider from "./popUpContext";
import { TabsProvider } from "./tabsContext";
import { TypesProvider } from "./typesContext";
import { ReactFlowProvider } from "reactflow";
import { UndoRedoProvider } from "./undoRedoContext";
import { SSEProvider } from "./SSEContext";
export default function ContextWrapper({ children }: { children: ReactNode }) {
//element to wrap all context

View file

@ -1,5 +1,4 @@
import { createContext } from "react";
import React, { useState } from "react";
import React, { createContext, useState } from "react";
// context to set JSX element on the DOM
export const PopUpContext = createContext({

View file

@ -1,33 +1,33 @@
import _ from "lodash";
import {
createContext,
useEffect,
useState,
useRef,
ReactNode,
createContext,
useContext,
useEffect,
useRef,
useState,
} from "react";
import { addEdge } from "reactflow";
import ShortUniqueId from "short-unique-id";
import {
deleteFlowFromDatabase,
downloadFlowsFromDatabase,
readFlowsFromDatabase,
saveFlowToDatabase,
updateFlowInDatabase,
uploadFlowsToDatabase,
} from "../controllers/API";
import { APIClassType, APITemplateType } from "../types/api";
import { FlowType, NodeType } from "../types/flow";
import { TabsContextType, TabsState } from "../types/tabs";
import {
updateIds,
updateTemplate,
getRandomDescription,
getRandomName,
updateIds,
updateTemplate,
} from "../utils";
import { alertContext } from "./alertContext";
import { typesContext } from "./typesContext";
import { APIClassType, APITemplateType } from "../types/api";
import ShortUniqueId from "short-unique-id";
import { addEdge } from "reactflow";
import {
readFlowsFromDatabase,
deleteFlowFromDatabase,
saveFlowToDatabase,
downloadFlowsFromDatabase,
uploadFlowsToDatabase,
updateFlowInDatabase,
} from "../controllers/API";
import _ from "lodash";
const uid = new ShortUniqueId({ length: 5 });
@ -108,7 +108,7 @@ export function TabsProvider({ children }: { children: ReactNode }) {
// function loadCookie(cookie: string) {
// if (cookie && Object.keys(templates).length > 0) {
// let cookieObject: LangFlowState = JSON.parse(cookie);
// let cookieObject: LangflowState = JSON.parse(cookie);
// try {
// cookieObject.flows.forEach((flow) => {
// if (!flow.data) {

View file

@ -1,8 +1,8 @@
import { createContext, ReactNode, useEffect, useState } from "react";
import { Node } from "reactflow";
import { typesContextType } from "../types/typesContext";
import { getAll } from "../controllers/API";
import { APIKindType } from "../types/api";
import { typesContextType } from "../types/typesContext";
//context to share types adn functions from nodes to flow

View file

@ -1,3 +1,4 @@
import { cloneDeep } from "lodash";
import {
createContext,
useCallback,
@ -6,7 +7,6 @@ import {
useState,
} from "react";
import { Edge, Node, useReactFlow } from "reactflow";
import { cloneDeep } from "lodash";
import { TabsContext } from "./tabsContext";
type undoRedoContextType = {

View file

@ -1,15 +1,15 @@
import {
BuildStatusTypeAPI,
errorsTypeAPI,
InitTypeAPI,
UploadFileTypeAPI,
APIClassType,
PromptTypeAPI,
} from "./../../types/api/index";
import { APIObjectType, sendAllProps } from "../../types/api/index";
import axios, { AxiosResponse } from "axios";
import { FlowStyleType, FlowType } from "../../types/flow";
import { ReactFlowJsonObject } from "reactflow";
import { APIObjectType, sendAllProps } from "../../types/api/index";
import { FlowStyleType, FlowType } from "../../types/flow";
import {
APIClassType,
BuildStatusTypeAPI,
InitTypeAPI,
PromptTypeAPI,
UploadFileTypeAPI,
errorsTypeAPI,
} from "./../../types/api/index";
/**
* Fetches all objects from the API endpoint.
@ -339,10 +339,3 @@ export async function uploadFile(
formData.append("file", file);
return await axios.post(`/api/v1/upload/${id}`, formData);
}
export async function postCustomComponent(
code: string,
apiClass: APIClassType
): Promise<AxiosResponse<APIClassType>> {
return await axios.post(`/api/v1/custom_component`, { code });
}

View file

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

View file

@ -145,6 +145,60 @@ The cursor: default; property value restores the browser's default cursor style
@layer components {
.round-buttons-position {
@apply fixed right-4
}
.side-bar-arrangement {
@apply flex h-full w-52 flex-col overflow-hidden border-r scrollbar-hide
}
.side-bar-search-div-placement {
@apply relative mx-auto mb-2 mt-2 flex items-center
}
.side-bar-components-icon {
@apply h-6 w-4 text-ring
}
.side-bar-components-text {
@apply w-full truncate pr-1 text-xs text-foreground
}
.side-bar-components-div-form {
@apply flex w-full items-center justify-between rounded-md rounded-l-none border border-l-0 border-dashed border-ring bg-white px-3 py-1 text-sm
}
.side-bar-components-border {
@apply cursor-grab rounded-l-md border-l-8
}
.side-bar-components-gap {
@apply flex flex-col gap-2 p-2
}
.side-bar-components-div-arrangement {
@apply w-full overflow-auto scrollbar-hide
}
.search-icon {
@apply absolute inset-y-0 right-0 flex items-center py-1.5 pr-5
}
.extra-side-bar-save-disable {
@apply text-muted-foreground
}
.extra-side-bar-save-disable:hover {
@apply hover:text-accent-foreground
}
.side-bar-button-size {
@apply h-5 w-5
}
.side-bar-button-size:hover {
@apply hover:text-accent-foreground
}
.side-bar-buttons-arrangement {
@apply mb-2 mt-2 flex w-full items-center justify-between gap-2 px-2
}
.extra-side-bar-buttons {
@apply relative inline-flex w-full items-center justify-center rounded-md bg-background px-2 py-2 text-foreground shadow-sm ring-1 ring-inset ring-input transition-all duration-500 ease-in-out
}
.extra-side-bar-buttons:hover {
@apply hover:bg-muted
}
.button-div-style {
@apply gap-2 flex
}
.input-primary:focus{
@apply focus:placeholder-transparent focus:ring-ring focus:border-ring
}
@ -163,4 +217,701 @@ The cursor: default; property value restores the browser's default cursor style
.input-dialog{
@apply text-ring cursor-pointer bg-transparent
}
.message-button {
@apply message-button-position flex h-12 w-12 items-center justify-center rounded-full bg-border px-3 py-1 shadow-md transition-all
}
.round-button-form {
@apply flex h-12 w-12 cursor-pointer justify-center rounded-full bg-border px-3 py-1 shadow-md
}
.round-button-div {
@apply flex items-center gap-3
}
.build-trigger-loading-icon {
@apply stroke-build-trigger
}
.build-trigger-icon {
@apply w-6 fill-build-trigger stroke-1 stroke-build-trigger
}
.message-button-position {
@apply fixed bottom-4 right-4
}
.message-button-icon {
@apply fill-chat-trigger stroke-chat-trigger stroke-1
}
.disabled-message-button-icon {
@apply fill-chat-trigger-disabled stroke-chat-trigger-disabled stroke-1
}
.components-disclosure-arrangement {
@apply -mt-px flex w-full select-none items-center justify-between border-y border-y-input bg-muted px-3 py-2
}
.components-disclosure-title {
@apply flex items-center text-sm text-primary
}
.components-disclosure-div {
@apply flex gap-2
}
.flow-page-positioning {
@apply h-full w-full overflow-hidden
}
.logspace-page-icon {
@apply absolute bottom-2 left-7 flex h-6 cursor-pointer flex-col items-center justify-start overflow-hidden rounded-lg bg-foreground px-2 text-center font-sans text-xs tracking-wide text-secondary transition-all duration-500 ease-in-out
}
.logspace-page-icon:hover {
@apply hover:h-12
}
.flex-max-width {
@apply flex w-full
}
.main-page-panel {
@apply flex-max-width h-full flex-col overflow-auto bg-muted px-16
}
.main-page-nav-arrangement {
@apply flex-max-width justify-between px-6 py-12 pb-2
}
.main-page-nav-title {
@apply flex items-center justify-center gap-2 text-2xl font-semibold
}
.main-page-nav-button {
@apply mr-2 w-4
}
.main-page-description-text {
@apply flex w-[60%] px-6 pb-14 text-muted-foreground
}
.main-page-flows-display {
@apply grid w-full gap-4 p-4 md:grid-cols-2 lg:grid-cols-4
}
.community-page-arrangement {
@apply flex-max-width h-full flex-col overflow-auto bg-muted px-16
}
.community-page-nav-arrangement {
@apply flex-max-width justify-between px-6 py-12 pb-2
}
.community-page-nav-title {
@apply flex items-center justify-center gap-2 text-2xl font-semibold
}
.community-page-nav-button {
@apply flex gap-2
}
.community-page-description-text {
@apply flex w-[70%] px-6 pb-8 text-muted-foreground
}
.community-pages-flows-panel {
@apply grid w-full gap-4 p-4 md:grid-cols-2 lg:grid-cols-4
}
.generic-node-div {
@apply relative flex w-96 flex-col justify-center rounded-lg bg-background
}
.generic-node-div-title {
@apply flex w-full items-center justify-between gap-8 rounded-t-lg border-b bg-muted p-4
}
.generic-node-title-arrangement {
@apply flex-max-width items-center truncate
}
.generic-node-icon {
@apply h-10 w-10 rounded p-1
}
.generic-node-tooltip-div {
@apply ml-2 truncate
}
.generic-node-validation-div {
@apply max-h-96 overflow-auto
}
.generic-node-status-position {
@apply relative top-[3px] h-5 w-5
}
.generic-node-status-animation {
@apply hidden h-4 w-4 animate-spin rounded-full bg-ring opacity-0
}
.generic-node-status {
@apply h-4 w-4 rounded-full opacity-100
}
.green-status {
@apply generic-node-status bg-status-green
}
.red-status {
@apply generic-node-status bg-status-red
}
.yellow-status {
@apply generic-node-status bg-status-yellow
}
.status-build-animation {
@apply hidden h-4 w-4 animate-spin rounded-full bg-ring opacity-0
}
.status-div {
@apply absolute w-4 duration-200 ease-in-out
}
.status-div:hover {
@apply hover:text-accent-foreground hover:transition-all
}
.generic-node-desc {
@apply h-full w-full py-5 text-foreground
}
.generic-node-desc-text {
@apply w-full px-5 pb-3 text-sm text-muted-foreground
}
.alert-icon {
@apply h-5 w-5
}
.alert-font-size {
@apply text-sm font-medium
}
.error-build-message {
@apply mt-6 w-96 cursor-pointer rounded-md bg-error-background p-4 shadow-xl
}
.error-build-message-circle {
@apply text-status-red alert-icon
}
.error-build-text {
@apply text-error-foreground
}
.error-build-foreground {
@apply error-build-text alert-font-size
}
.error-build-message-div {
@apply mt-2 text-sm error-build-text
}
.error-build-message-list {
@apply list-disc space-y-1 pl-5
}
.success-alert {
@apply mt-6 w-96 rounded-md bg-success-background p-4 shadow-xl
}
.success-alert-icon {
@apply alert-icon text-status-green
}
.success-alert-message {
@apply alert-font-size text-success-foreground
}
.card-component-title-display {
@apply round-button-div flex-max-width
}
.card-component-image {
@apply flex h-7 w-7 items-center justify-center rounded-full text-2xl
}
.card-component-title-size {
@apply inline-block w-full flex-1 break-words truncate-doubleline
}
.card-component-delete-button {
@apply flex self-start
}
.card-component-delete-icon {
@apply h-4 w-4 text-primary opacity-0 transition-all group-hover:opacity-100
}
.card-component-desc {
@apply pb-2 pt-2
}
.card-component-desc-text {
@apply truncate-doubleline
}
.card-component-footer-arrangement {
@apply flex-max-width items-end justify-between gap-2
}
.card-component-footer {
@apply flex flex-wrap gap-2
}
.unused-side-bar-aside {
@apply flex flex-shrink-0 flex-col overflow-hidden border-r transition-all duration-500
}
.unused-side-bar-arrangement {
@apply flex h-full w-52 flex-col items-start overflow-y-auto border bg-background scrollbar-hide
}
.unused-side-bar-division {
@apply flex-max-width flex-grow flex-col
}
.unused-side-bar-nav {
@apply flex-1 space-y-1
}
.unused-side-bar-link {
@apply flex-max-width items-center rounded-md py-2 pl-2 text-sm font-medium
}
.unused-side-bar-link-colors-true {
@apply bg-muted text-foreground
}
.unused-side-bar-link-colors-false {
@apply bg-background text-muted-foreground hover:bg-muted hover:text-foreground
}
.unused-side-bar-icon {
@apply mr-3 flex-shrink-0 h-6 w-6
}
.unused-side-bar-icon-false {
@apply text-ring group-hover:text-accent-foreground
}
.unused-side-bar-disclosure {
@apply unused-side-bar-link pr-1 text-left
}
.unused-side-bar-disclosure:focus {
@apply focus:outline-none focus:ring-1 focus:ring-ring
}
.unused-side-bar-disclosure-icon {
@apply unused-side-bar-icon text-ring group-hover:text-accent-foreground
}
.unused-side-bar-svg-true {
@apply text-ring rotate-90
}
.unused-side-bar-svg {
@apply ml-3 h-5 w-5 flex-shrink-0 duration-150 ease-in-out group-hover:text-accent-foreground
}
.unused-side-bar-disclosure-panel {
@apply flex w-full items-center rounded-md py-2 pl-11 pr-2 text-sm font-medium
}
.code-area-component {
@apply pointer-events-none w-full cursor-not-allowed
}
.code-area-input-positioning {
@apply flex-max-width items-center
}
.code-area-external-link {
@apply w-6 h-6 ml-3
}
.code-area-external-link:hover {
@apply hover:text-accent-foreground
}
.dropdown-component-outline {
@apply input-edit-node relative pr-8
}
.dropdown-component-false-outline {
@apply input-primary py-2 pl-3 pr-10 text-left
}
.dropdown-component-display {
@apply block w-full truncate bg-background
}
.dropdown-component-arrow {
@apply pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2
}
.dropdown-component-arrow-color {
@apply h-5 w-5 extra-side-bar-save-disable
}
.dropdown-component-options {
@apply z-10 mt-1 max-h-60 overflow-auto rounded-md bg-background py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm
}
.dropdown-component-true-options {
@apply dropdown-component-options w-[215px]
}
.dropdown-component-false-options {
@apply dropdown-component-options w-full
}
.dropdown-component-option {
@apply relative cursor-default select-none
}
.dropdown-component-false-option {
@apply dropdown-component-option py-0.5 pl-3 pr-12
}
.dropdown-component-true-option {
@apply dropdown-component-option py-2 pl-3 pr-9
}
.dropdown-component-choosal {
@apply absolute inset-y-0 right-0 flex items-center pr-4
}
.dropdown-component-check-icon {
@apply h-5 w-5 text-black
}
.edit-flow-arrangement {
@apply flex justify-between
}
.edit-flow-span {
@apply ml-10 animate-pulse text-status-red
}
.float-component-pointer {
@apply pointer-events-none cursor-not-allowed
}
.header-menu-bar {
@apply flex items-center gap-0.5 rounded-md px-1.5 py-1 text-sm font-medium
}
.header-menu-bar-display {
@apply flex max-w-[200px] items-center gap-2
}
.header-menu-flow-name {
@apply flex-1 truncate
}
.header-menu-options {
@apply mr-2 h-4 w-4
}
.header-arrangement {
@apply flex-max-width h-12 items-center justify-between border-b bg-muted
}
.header-start-display {
@apply flex w-96 items-center justify-start gap-2
}
.header-end-division {
@apply flex w-96 justify-end px-2
}
.header-end-display {
@apply ml-auto mr-2 flex items-center gap-5
}
.header-github-link-box {
@apply border border-input h-9 px-3 pr-0 rounded-md inline-flex shadow-sm items-center justify-center
}
.header-github-link {
@apply text-sm font-medium disabled:opacity-50 disabled:pointer-events-none ring-offset-background text-muted-foreground header-github-link-box
}
.header-github-link:focus-visible {
@apply focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2
}
.header-github-link:hover {
@apply hover:bg-accent hover:text-accent-foreground
}
.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
}
.header-notifications-box {
@apply fixed left-0 top-0 h-screen w-screen
}
.header-notifications {
@apply absolute right-[3px] h-1.5 w-1.5 rounded-full bg-destructive
}
.input-component-div {
@apply pointer-events-none relative cursor-not-allowed
}
.input-component-button {
@apply absolute inset-y-0 right-0 items-center text-muted-foreground
}
.input-component-true-button {
@apply input-component-button pr-2
}
.input-component-false-button {
@apply input-component-button px-4
}
.input-component-true-svg {
@apply absolute bottom-0.5 right-2 side-bar-button-size
}
.input-component-false-svg {
@apply absolute bottom-2 right-3 side-bar-button-size
}
.input-file-component {
@apply flex-max-width items-center
}
.toggle-component-switch {
@apply relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out
}
.toggle-component-switch:focus {
@apply focus:outline-none focus:ring-1 focus:ring-primary focus:ring-offset-1
}
.toggle-component-span {
@apply pointer-events-none relative inline-block h-5 w-5 transform rounded-full shadow ring-0 transition duration-200 ease-in-out
}
.toggle-component-second-span {
@apply absolute inset-0 flex h-full w-full items-center justify-center transition-opacity
}
.app-div {
@apply fixed bottom-5 left-5 flex flex-col-reverse
}
.chat-input-modal-txtarea {
@apply form-input block w-full rounded-md border-ring pr-10 custom-scroll sm:text-sm
}
.chat-input-modal-div {
@apply absolute bottom-0.5 right-3
}
.chat-input-modal-lock {
@apply side-bar-button-size animate-pulse text-ring
}
.chat-input-modal-send {
@apply side-bar-button-size text-ring hover:text-muted-foreground
}
.code-block-modal {
@apply flex items-center justify-between px-4 py-1.5
}
.code-block-modal-span {
@apply text-xs lowercase text-background
}
.code-block-modal-button {
@apply flex items-center gap-1.5 rounded bg-none p-1 text-xs text-background
}
.chat-message-modal {
@apply flex-max-width py-2 pl-2
}
.chat-message-modal-div {
@apply my-3 flex h-8 w-8 items-center justify-center overflow-hidden rounded-full
}
.chat-message-modal-img {
@apply absolute scale-150 transition-opacity duration-500
}
.chat-message-modal-display {
@apply flex-max-width items-center text-start
}
.chat-message-modal-text {
@apply relative inline-block w-full text-start text-sm font-normal text-muted-foreground
}
.chat-message-modal-icon-div {
@apply absolute -left-2 -top-1 cursor-pointer
}
.chat-message-modal-thought {
@apply ml-3 inline-block h-full w-[95%] rounded-md border border-ring bg-muted px-2 pb-3 pt-3 text-start text-muted-foreground chat-message-modal-thought-cursor
}
.chat-message-modal-thought-cursor {
@apply cursor-pointer scrollbar-hide overflow-scroll
}
.chat-message-modal-markdown {
@apply w-full px-4 pb-3 pr-8 pt-3
}
.chat-message-modal-markdown-span {
@apply mt-1 animate-pulse cursor-default
}
.chat-message-modal-alert {
@apply inline-block px-3 text-start text-muted-foreground
}
.file-card-modal-image-div {
@apply absolute right-0 top-0 rounded-bl-lg bg-muted px-1 text-sm font-bold text-foreground
}
.file-card-modal-image-button {
@apply px-2 py-1 text-ring
}
.file-card-modal-button {
@apply flex w-1/2 items-center justify-between rounded border border-ring bg-muted px-2 py-2 text-foreground shadow hover:drop-shadow-lg
}
.file-card-modal-div {
@apply mr-2 flex-max-width items-center gap-2 text-current
}
.file-card-modal-footer {
@apply flex flex-col items-start
}
.file-card-modal-name {
@apply truncate text-sm text-current
}
.file-card-modal-type {
@apply truncate text-xs text-ring
}
.send-message-modal-transition {
@apply fixed inset-0 bg-black bg-opacity-80 backdrop-blur-sm transition-opacity
}
.chat-modal-box {
@apply fixed inset-0 z-10 overflow-y-auto
}
.chat-modal-box-div {
@apply flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0
}
.chat-modal-dialog-panel {
@apply relative flex h-[95%] w-[690px] transform flex-col justify-between overflow-hidden rounded-lg bg-background text-left shadow-xl drop-shadow-2xl transition-all
}
.chat-modal-dialog-panel-div {
@apply relative w-full p-4
}
.chat-modal-dialog-trash-panel {
@apply absolute right-10 top-2 z-30 text-muted-foreground hover:text-status-red
}
.chat-modal-dialog-x-panel {
@apply absolute right-2 top-1.5 z-30 text-muted-foreground hover:text-status-red
}
.chat-modal-dialog-history {
@apply flex-max-width h-full flex-col items-center overflow-scroll border-t bg-background scrollbar-hide
}
.chat-modal-dialog-span-box {
@apply flex-max-width h-full flex-col items-center justify-center text-center align-middle
}
.chat-modal-dialog-desc {
@apply w-2/4 rounded-md border border-input bg-muted px-6 py-8
}
.chat-modal-input-div {
@apply flex-max-width flex-col items-center justify-between border-t bg-background p-3
}
.chat-modal-input {
@apply relative mt-1 w-full rounded-md shadow-sm
}
.code-area-modal-editor-div {
@apply mt-2 flex-max-width h-full
}
.code-area-modal-editor-box {
@apply h-[300px] w-full rounded-lg border-[1px] border-ring custom-scroll
}
.edit-node-modal-variable {
@apply h-5 w-5 stroke-2 pe-1 text-muted-foreground
}
.edit-node-modal-span {
@apply text-sm font-semibold text-primary
}
.edit-node-modal-arrangement {
@apply flex-max-width h-fit max-h-[400px]
}
.edit-node-modal-box {
@apply w-full rounded-lg border-[1px] border-input bg-background
}
.edit-node-modal-table {
@apply flex h-fit flex-col gap-5
}
.edit-node-modal-table-header {
@apply h-10 border-input text-xs font-medium text-ring
}
.edit-node-modal-table-cell {
@apply p-0 text-center text-sm text-foreground truncate sm:px-3
}
.edit-node-modal-second-cell {
@apply w-[300px] p-0 text-center text-xs text-foreground
}
.generic-modal-txtarea-div {
@apply mt-2 flex-max-width h-full
}
.button-box-modal-div {
@apply flex transform flex-col items-center justify-center rounded-lg border border-ring text-center shadow hover:scale-105 hover:shadow-lg
}
.dialog-header-modal-div {
@apply absolute left-0 top-2 z-50 hidden pl-4 pt-4 sm:block
}
.dialog-header-modal-button {
@apply rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2
}
.dialog-modal-examples-div {
@apply h-full w-full overflow-y-auto scrollbar-hide
}
.dialog-modal-example-true {
@apply mx-auto flex flex-row flex-wrap items-start justify-center overflow-auto
}
.dialog-modal-example-false {
@apply flex flex-row items-center justify-center
}
.dialog-modal-button-box-div {
@apply flex-max-width h-full items-center justify-evenly
}
.document-icon {
@apply h-10 w-10 flex-shrink-0
}
.loading-component-div {
@apply flex items-center justify-center align-middle
}
.dialog-modal-footer {
@apply mt-2 flex-max-width items-center justify-center
}
.dialog-modal-footer-link {
@apply flex items-center justify-center text-muted-foreground
}
.node-modal-div {
@apply fixed inset-0 bg-ring bg-opacity-75 transition-opacity
}
.node-modal-dialog-arrangement {
@apply fixed inset-0 z-10 overflow-y-auto
}
.node-modal-dialog-div {
@apply flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0
}
.node-modal-dialog-panel {
@apply relative flex h-[600px] w-[700px] transform flex-col justify-between overflow-hidden rounded-lg bg-background text-left shadow-xl transition-all sm:my-8
}
.node-modal-dialog-panel-div {
@apply absolute right-0 top-0 z-50 hidden pr-4 pt-4 sm:block
}
.node-modal-dialog-button {
@apply rounded-md text-ring hover:text-accent-foreground
}
.node-modal-dialog-icon-div {
@apply flex-max-width h-full flex-col items-center justify-center
}
.node-modal-icon-arrangement {
@apply z-10 flex-max-width justify-center pb-4 shadow-sm
}
.node-modal-icon {
@apply mt-4 h-10 w-10 rounded p-1
}
.node-modal-title-div {
@apply mt-4 text-center sm:ml-4 sm:text-left
}
.node-modal-title {
@apply text-lg font-medium leading-10 text-foreground
}
.node-modal-template-div {
@apply flex-max-width h-full flex-row items-center justify-center gap-4 bg-input p-4
}
.node-modal-template {
@apply w-full rounded-lg bg-background px-4 shadow sm:p-4
}
.node-modal-template-column {
@apply flex h-full flex-col gap-5
}
.node-modal-button-box {
@apply flex-max-width flex-row-reverse bg-input px-4 pb-3
}
.node-modal-button {
@apply inline-flex w-full justify-center rounded-md border border-transparent bg-status-red px-4 py-2 text-base font-medium text-background shadow-sm hover:bg-ring sm:ml-3 sm:w-auto sm:text-sm
}
.node-modal-button:focus {
@apply focus:outline-none focus:ring-1 focus:ring-ring focus:ring-offset-1
}
.prompt-modal-icon-box {
@apply mx-auto mt-4 flex h-12 w-12 flex-shrink-0 items-center justify-center rounded-full bg-almost-light-blue sm:mx-0 sm:h-10 sm:w-10
}
.prompt-modal-icon {
@apply h-6 w-6 text-almost-medium-blue
}
.prompt-modal-txtarea-arrangement {
@apply flex-max-width h-full flex-row items-center justify-center gap-4 overflow-auto bg-accent p-4
}
.prompt-modal-txtarea-box {
@apply h-full w-full overflow-hidden rounded-lg bg-background px-4 py-5 shadow sm:p-6
}
.prompt-modal-txtarea {
@apply form-input h-full w-full rounded-lg border-ring
}
.txtarea-modal-arrangement {
@apply flex h-full w-full flex-row items-center justify-center gap-4 bg-input p-4
}
.txtarea-modal-box {
@apply w-full overflow-hidden rounded-lg bg-background px-4 py-5 shadow sm:p-6
}
.txtarea-modal-input {
@apply form-input h-full w-full
}
.api-modal-tabs {
@apply w-full h-full overflow-hidden text-center bg-muted rounded-md border
}
.api-modal-tablist-div {
@apply flex items-center justify-between px-2
}
.api-modal-tabs-content {
@apply overflow-hidden w-full h-full px-4 pb-4 -mt-1
}
.api-modal-accordion-display {
@apply flex w-full h-full mt-2
}
.api-modal-table-arrangement {
@apply flex flex-col gap-5 h-fit
}
.icons-parameters-comp{
@apply ml-3 h-6 w-6
}
}

View file

@ -1,9 +1,8 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { BrowserRouter } from "react-router-dom";
import App from "./App";
import ContextWrapper from "./contexts";
import reportWebVitals from "./reportWebVitals";
import "./index.css";

View file

@ -1,42 +1,15 @@
import { useContext, useEffect, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/theme-twilight";
import "ace-builds/src-noconflict/ext-language_tools";
import { useContext, useEffect, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
// import "ace-builds/webpack-resolver";
import { darkContext } from "../../contexts/darkContext";
import { Check, Clipboard, Code2 } from "lucide-react";
import { Prism as SyntaxHighlighter } from "react-syntax-highlighter";
import { oneDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { FlowType } from "../../types/flow/index";
import { getCurlCode, getPythonApiCode, getPythonCode } from "../../constants";
import { EXPORT_CODE_DIALOG } from "../../constants";
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "../../components/ui/tabs";
import { Check, Clipboard, Code2 } from "lucide-react";
import {
Table,
TableBody,
TableCaption,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../../components/ui/table";
import { buildTweaks, classNames, limitScrollFieldsModal } from "../../utils";
import AccordionComponent from "../../components/AccordionComponent";
import ShadTooltip from "../../components/ShadTooltipComponent";
import CodeAreaComponent from "../../components/codeAreaComponent";
import Dropdown from "../../components/dropdownComponent";
import FloatComponent from "../../components/floatComponent";
@ -47,9 +20,38 @@ import IntComponent from "../../components/intComponent";
import PromptAreaComponent from "../../components/promptComponent";
import TextAreaComponent from "../../components/textAreaComponent";
import ToggleShadComponent from "../../components/toggleShadComponent";
import ShadTooltip from "../../components/ShadTooltipComponent";
import { cloneDeep, filter } from "lodash";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../../components/ui/table";
import {
Tabs,
TabsContent,
TabsList,
TabsTrigger,
} from "../../components/ui/tabs";
import {
EXPORT_CODE_DIALOG,
getCurlCode,
getPythonApiCode,
getPythonCode,
} from "../../constants";
import { darkContext } from "../../contexts/darkContext";
import { TabsContext } from "../../contexts/tabsContext";
import { FlowType } from "../../types/flow/index";
import { buildTweaks, classNames } from "../../utils";
export default function ApiModal({ flow }: { flow: FlowType }) {
const [open, setOpen] = useState(true);
@ -61,7 +63,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
const [openAccordion, setOpenAccordion] = useState([]);
const tweak = useRef([]);
const tweaksList = useRef([]);
const { setTweak, getTweak } = useContext(TabsContext);
const { setTweak, getTweak, tabsState } = useContext(TabsContext);
const copyToClipboard = () => {
if (!navigator.clipboard || !navigator.clipboard.writeText) {
return;
@ -75,9 +77,9 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
}, 2000);
});
};
const pythonApiCode = getPythonApiCode(flow, tweak.current);
const curl_code = getCurlCode(flow, tweak.current);
const pythonCode = getPythonCode(flow, tweak.current);
const pythonApiCode = getPythonApiCode(flow, tweak.current, tabsState);
const curl_code = getCurlCode(flow, tweak.current, tabsState);
const pythonCode = getPythonCode(flow, tweak.current, tabsState);
const tweaksCode = buildTweaks(flow);
const tabs = [
{
@ -111,7 +113,9 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
startTweaks();
}
} else {
startTweaks();
if (tweak?.current) {
startTweaks();
}
}
}, [closeEdit]);
@ -276,7 +280,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
<Tabs
value={activeTab}
className="h-full w-full overflow-hidden rounded-md border bg-muted text-center"
className="api-modal-tabs"
onValueChange={(value) => {
setActiveTab(value);
if (value === "3") {
@ -284,7 +288,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
}
}}
>
<div className="flex items-center justify-between px-2">
<div className="api-modal-tablist-div">
<TabsList>
{tabs.map((tab, index) => (
<TabsTrigger key={index} value={index.toString()}>
@ -308,12 +312,12 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
{tabs.map((tab, index) => (
<TabsContent
value={index.toString()}
className="-mt-1 h-full w-full overflow-hidden px-4 pb-4"
className="api-modal-tabs-content"
key={index} // Remember to add a unique key prop
>
{index < 3 ? (
<SyntaxHighlighter
className="h-[60vh] w-full overflow-auto"
className="h-[60vh] w-full overflow-auto custom-scroll"
language={tab.mode}
style={oneDark}
>
@ -321,7 +325,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</SyntaxHighlighter>
) : index === 3 ? (
<>
<div className="mt-2 flex h-full w-full">
<div className="api-modal-according-display">
<div
className={classNames(
"h-[60vh] w-full rounded-lg bg-muted",
@ -337,7 +341,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
trigger={t["data"]["id"]}
open={openAccordion}
>
<div className="flex h-fit flex-col gap-5">
<div className="api-modal-table-arrangement">
<Table className="table-fixed bg-muted outline-1">
<TableHeader className="h-10 border-input text-xs font-medium text-ring">
<TableRow className="dark:border-b-muted">
@ -418,7 +422,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
) : t.data.node.template[n]
.multiline ? (
<ShadTooltip
delayDuration={1000}
content={buildContent(
t.data.node.template[
n
@ -506,7 +509,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
) : t.data.node.template[n]
.type === "file" ? (
<ShadTooltip
delayDuration={1000}
content={buildContent(
getValue(
t.data.node.template[n]
@ -622,7 +624,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
) : t.data.node.template[n]
.type === "prompt" ? (
<ShadTooltip
delayDuration={1000}
content={buildContent(
getValue(
t.data.node.template[n]
@ -659,7 +660,6 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
) : t.data.node.template[n]
.type === "code" ? (
<ShadTooltip
delayDuration={1000}
content={buildContent(
getValue(
t.data.node.template[n]
@ -720,7 +720,7 @@ export default function ApiModal({ flow }: { flow: FlowType }) {
</div>
))}
{/*
{/*
<div className="flex flex-col gap-5 bg-muted">
<Table className="table-fixed bg-muted outline-1">
<TableHeader className="border-gray-200 text-gray-500 text-xs font-medium h-10">

View file

@ -1,26 +1,17 @@
import { Variable } from "lucide-react";
import { useContext, useEffect, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { NodeDataType } from "../../types/flow";
import { classNames, limitScrollFieldsModal } from "../../utils";
import { typesContext } from "../../contexts/typesContext";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../../components/ui/table";
import ToggleShadComponent from "../../components/toggleShadComponent";
import InputListComponent from "../../components/inputListComponent";
import TextAreaComponent from "../../components/textAreaComponent";
import InputComponent from "../../components/inputComponent";
import FloatComponent from "../../components/floatComponent";
import Dropdown from "../../components/dropdownComponent";
import IntComponent from "../../components/intComponent";
import InputFileComponent from "../../components/inputFileComponent";
import PromptAreaComponent from "../../components/promptComponent";
import CodeAreaComponent from "../../components/codeAreaComponent";
import Dropdown from "../../components/dropdownComponent";
import FloatComponent from "../../components/floatComponent";
import InputComponent from "../../components/inputComponent";
import InputFileComponent from "../../components/inputFileComponent";
import InputListComponent from "../../components/inputListComponent";
import IntComponent from "../../components/intComponent";
import PromptAreaComponent from "../../components/promptComponent";
import TextAreaComponent from "../../components/textAreaComponent";
import ToggleShadComponent from "../../components/toggleShadComponent";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
@ -30,9 +21,18 @@ import {
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { Badge } from "../../components/ui/badge";
import { Variable } from "lucide-react";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "../../components/ui/table";
import { PopUpContext } from "../../contexts/popUpContext";
import { typesContext } from "../../contexts/typesContext";
import { NodeDataType } from "../../types/flow";
import { classNames, limitScrollFieldsModal } from "../../utils";
export default function EditNodeModal({ data }: { data: NodeDataType }) {
const [open, setOpen] = useState(true);
@ -90,27 +90,25 @@ export default function EditNodeModal({ data }: { data: NodeDataType }) {
<DialogDescription>
{data.node?.description}
<div className="flex pt-3">
<Variable className="h-5 w-5 stroke-2 pe-1 text-muted-foreground "></Variable>
<span className="text-sm font-semibold text-primary">
Parameters
</span>
<Variable className="edit-node-modal-variable "></Variable>
<span className="edit-node-modal-span">Parameters</span>
</div>
</DialogDescription>
</DialogHeader>
<div className="flex h-fit max-h-[400px] w-full">
<div className="edit-node-modal-arrangement">
<div
className={classNames(
"w-full rounded-lg border-[1px] border-input bg-background",
"edit-node-modal-box",
nodeLength > limitScrollFieldsModal
? "overflow-scroll overflow-x-hidden custom-scroll"
: "overflow-hidden"
)}
>
{nodeLength > 0 && (
<div className="flex h-fit flex-col gap-5">
<div className="edit-node-modal-table">
<Table className="table-fixed bg-muted outline-1">
<TableHeader className="h-10 border-input text-xs font-medium text-ring">
<TableHeader className="edit-node-modal-table-header">
<TableRow className="">
<TableHead className="h-7 text-center">PARAM</TableHead>
<TableHead className="h-7 p-0 text-center">

View file

@ -1,14 +1,14 @@
import { useState } from "react";
import InputListComponent from "../../../../components/inputListComponent";
import Dropdown from "../../../../components/dropdownComponent";
import TextAreaComponent from "../../../../components/textAreaComponent";
import InputComponent from "../../../../components/inputComponent";
import ToggleComponent from "../../../../components/toggleComponent";
import FloatComponent from "../../../../components/floatComponent";
import IntComponent from "../../../../components/intComponent";
import InputFileComponent from "../../../../components/inputFileComponent";
import PromptAreaComponent from "../../../../components/promptComponent";
import CodeAreaComponent from "../../../../components/codeAreaComponent";
import Dropdown from "../../../../components/dropdownComponent";
import FloatComponent from "../../../../components/floatComponent";
import InputComponent from "../../../../components/inputComponent";
import InputFileComponent from "../../../../components/inputFileComponent";
import InputListComponent from "../../../../components/inputListComponent";
import IntComponent from "../../../../components/intComponent";
import PromptAreaComponent from "../../../../components/promptComponent";
import TextAreaComponent from "../../../../components/textAreaComponent";
import ToggleComponent from "../../../../components/toggleComponent";
import { classNames } from "../../../../utils";
export default function ModalField({

View file

@ -1,6 +1,8 @@
import { Dialog, Transition } from "@headlessui/react";
import { X } from "lucide-react";
import { Fragment, useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import { typesContext } from "../../contexts/typesContext";
import { NodeDataType } from "../../types/flow";
import {
classNames,
@ -9,9 +11,7 @@ import {
nodeIconsLucide,
toTitleCase,
} from "../../utils";
import { typesContext } from "../../contexts/typesContext";
import ModalField from "./components/ModalField";
import { X } from "lucide-react";
export default function NodeModal({ data }: { data: NodeDataType }) {
const [open, setOpen] = useState(true);
@ -45,11 +45,11 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-ring bg-opacity-75 transition-opacity" />
<div className="node-modal-div" />
</Transition.Child>
<div className="fixed inset-0 z-10 overflow-y-auto">
<div className="flex h-full items-end justify-center p-4 text-center sm:items-center sm:p-0">
<div className="node-modal-dialog-arrangement">
<div className="node-modal-dialog-div">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
@ -59,11 +59,11 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative flex h-[600px] w-[700px] transform flex-col justify-between overflow-hidden rounded-lg bg-background text-left shadow-xl transition-all sm:my-8">
<div className=" absolute right-0 top-0 z-50 hidden pr-4 pt-4 sm:block">
<Dialog.Panel className="node-modal-dialog-panel">
<div className=" node-modal-dialog-panel-div">
<button
type="button"
className="rounded-md text-ring hover:text-accent-foreground"
className="node-modal-dialog-button"
onClick={() => {
setModalOpen(false);
}}
@ -72,30 +72,27 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
<X className="h-6 w-6" aria-hidden="true" />
</button>
</div>
<div className="flex h-full w-full flex-col items-center justify-center">
<div className="z-10 flex w-full justify-center pb-4 shadow-sm">
<div className="node-modal-dialog-icon-div">
<div className="node-modal-icon-arrangement">
<Icon
strokeWidth={1.5}
className="mt-4 h-10 w-10 rounded p-1"
className="node-modal-icon"
style={{
color:
nodeColors[types[data.type]] ?? nodeColors.unknown,
}}
/>
<div className="mt-4 text-center sm:ml-4 sm:text-left">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-10 text-foreground"
>
<div className="node-modal-title-div">
<Dialog.Title as="h3" className="node-modal-title">
{data.type}
</Dialog.Title>
</div>
</div>
<div className="flex h-full w-full flex-row items-center justify-center gap-4 bg-input p-4">
<div className="flex h-[445px] w-full">
<div className="node-modal-template-div">
<div className="flex-max-width h-[445px]">
<div
className={classNames(
"w-full rounded-lg bg-background px-4 shadow sm:p-4",
"node-modal-template",
Object.keys(data.node.template).filter(
(t) =>
t.charAt(0) !== "_" &&
@ -106,7 +103,7 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
: "overflow-hidden"
)}
>
<div className="flex h-full flex-col gap-5">
<div className="node-modal-template-column">
{Object.keys(data.node.template)
.filter(
(t) =>
@ -144,10 +141,10 @@ export default function NodeModal({ data }: { data: NodeDataType }) {
</div>
</div>
</div>
<div className="flex w-full flex-row-reverse bg-input px-4 pb-3">
<div className="node-modal-button-box">
<button
type="button"
className="inline-flex w-full justify-center rounded-md border border-transparent bg-status-red px-4 py-2 text-base font-medium text-background shadow-sm hover:bg-ring focus:outline-none focus:ring-1 focus:ring-ring focus:ring-offset-1 sm:ml-3 sm:w-auto sm:text-sm"
className="node-modal-button"
onClick={() => {
setModalOpen(false);
}}

View file

@ -0,0 +1,157 @@
import Convert from "ansi-to-html";
import DOMPurify from "dompurify";
import { MessageCircle, User2 } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import ReactMarkdown from "react-markdown";
import rehypeMathjax from "rehype-mathjax";
import remarkGfm from "remark-gfm";
import remarkMath from "remark-math";
import AiIcon from "../../../assets/Gooey Ring-5s-271px.svg";
import AiIconStill from "../../../assets/froze-flow.png";
import { ChatMessageType } from "../../../types/chat";
import { classNames } from "../../../utils";
import FileCard from "../fileComponent";
import { CodeBlock } from "./codeBlock";
export default function ChatMessage({
chat,
lockChat,
lastMessage,
}: {
chat: ChatMessageType;
lockChat: boolean;
lastMessage: boolean;
}) {
const convert = new Convert({ newline: true });
const [message, setMessage] = useState("");
const imgRef = useRef(null);
useEffect(() => {
setMessage(chat.message);
}, [chat.message]);
const [hidden, setHidden] = useState(true);
return (
<div
className={classNames(
"chat-message-modal",
chat.isSend ? "bg-background " : "bg-input"
)}
>
<div className={classNames("chat-message-modal-div")}>
{!chat.isSend && (
<div className="relative h-8 w-8">
<img
className={
"chat-message-modal-img " +
(lockChat ? "opacity-100" : "opacity-0")
}
src={lastMessage ? AiIcon : AiIconStill}
/>
<img
className={
"chat-message-modal-img " +
(lockChat ? "opacity-0" : "opacity-100")
}
src={AiIconStill}
/>
</div>
)}
{chat.isSend && <User2 className="-mb-1 h-6 w-6 text-primary " />}
</div>
{!chat.isSend ? (
<div className="chat-message-modal-display">
<div className="chat-message-modal-text">
{hidden && chat.thought && chat.thought !== "" && (
<div
onClick={() => setHidden((prev) => !prev)}
className="chat-message-modal-icon-div"
>
<MessageCircle className="h-5 w-5 animate-bounce " />
</div>
)}
{chat.thought && chat.thought !== "" && !hidden && (
<div
onClick={() => setHidden((prev) => !prev)}
className=" chat-message-modal-thought"
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(convert.toHtml(chat.thought)),
}}
></div>
)}
{chat.thought && chat.thought !== "" && !hidden && <br></br>}
<div className="chat-message-modal-markdown">
<div className="w-full">
<div className="w-full">
<ReactMarkdown
remarkPlugins={[remarkGfm, remarkMath]}
rehypePlugins={[rehypeMathjax]}
className="markdown prose text-muted-foreground "
components={{
code({ node, inline, className, children, ...props }) {
if (children.length) {
if (children[0] == "▍") {
return (
<span className="chat-message-modal-markdown-span">
</span>
);
}
children[0] = (children[0] as string).replace(
"`▍`",
"▍"
);
}
const match = /language-(\w+)/.exec(className || "");
return !inline ? (
<CodeBlock
key={Math.random()}
language={(match && match[1]) || ""}
value={String(children).replace(/\n$/, "")}
{...props}
/>
) : (
<code className={className} {...props}>
{children}
</code>
);
},
}}
>
{message}
</ReactMarkdown>
</div>
{chat.files && (
<div className="my-2 w-full">
{chat.files.map((file, index) => {
return (
<div key={index} className="my-2 w-full">
<FileCard
fileName={"Generated File"}
fileType={file.data_type}
content={file.data}
/>
</div>
);
})}
</div>
)}
</div>
</div>
</div>
</div>
) : (
<div className="flex w-full items-center">
<div className="chat-message-modal-alert ">
{message.split("\n").map((line, index) => (
<span key={index} className="text-muted-foreground ">
{line}
<br />
</span>
))}
</div>
</div>
)}
</div>
);
}

View file

@ -0,0 +1,415 @@
import { Dialog, Transition } from "@headlessui/react";
import { Eraser, MessagesSquare, X } from "lucide-react";
import { Fragment, useContext, useEffect, useRef, useState } from "react";
import { alertContext } from "../../contexts/alertContext";
import { typesContext } from "../../contexts/typesContext";
import { sendAllProps } from "../../types/api";
import { ChatMessageType } from "../../types/chat";
import { FlowType } from "../../types/flow";
import { validateNodes } from "../../utils";
import ChatInput from "./chatInput";
import ChatMessage from "./chatMessage";
import _ from "lodash";
import { getHealth } from "../../controllers/API";
export default function ChatModal({
flow,
open,
setOpen,
}: {
open: boolean;
setOpen: Function;
flow: FlowType;
}) {
const [chatValue, setChatValue] = useState("");
const [chatHistory, setChatHistory] = useState<ChatMessageType[]>([]);
const { reactFlowInstance } = useContext(typesContext);
const { setErrorData, setNoticeData } = useContext(alertContext);
const ws = useRef<WebSocket | null>(null);
const [lockChat, setLockChat] = useState(false);
const isOpen = useRef(open);
const messagesRef = useRef(null);
const id = useRef(flow.id);
useEffect(() => {
if (messagesRef.current) {
messagesRef.current.scrollTop = messagesRef.current.scrollHeight;
}
}, [chatHistory]);
useEffect(() => {
isOpen.current = open;
}, [open]);
useEffect(() => {
id.current = flow.id;
}, [flow.id]);
var isStream = false;
const addChatHistory = (
message: string,
isSend: boolean,
thought?: string,
files?: Array<any>
) => {
setChatHistory((old) => {
let newChat = _.cloneDeep(old);
if (files) {
newChat.push({ message, isSend, files, thought });
} else if (thought) {
newChat.push({ message, isSend, thought });
} else {
newChat.push({ message, isSend });
}
return newChat;
});
};
//add proper type signature for function
function updateLastMessage({
str,
thought,
end = false,
files,
}: {
str?: string;
thought?: string;
// end param default is false
end?: boolean;
files?: Array<any>;
}) {
setChatHistory((old) => {
let newChat = [...old];
if (str) {
if (end) {
newChat[newChat.length - 1].message = str;
} else {
newChat[newChat.length - 1].message =
newChat[newChat.length - 1].message + str;
}
}
if (thought) {
newChat[newChat.length - 1].thought = thought;
}
if (files) {
newChat[newChat.length - 1].files = files;
}
return newChat;
});
}
function handleOnClose(event: CloseEvent) {
if (isOpen.current) {
setErrorData({ title: event.reason });
setTimeout(() => {
connectWS();
setLockChat(false);
}, 1000);
}
}
function getWebSocketUrl(chatId, isDevelopment = false) {
const isSecureProtocol = window.location.protocol === "https:";
const webSocketProtocol = isSecureProtocol ? "wss" : "ws";
const host = isDevelopment ? "localhost:7860" : window.location.host;
const chatEndpoint = `/api/v1/chat/${chatId}`;
return `${
isDevelopment ? "ws" : webSocketProtocol
}://${host}${chatEndpoint}`;
}
function handleWsMessage(data: any) {
if (Array.isArray(data)) {
//set chat history
setChatHistory((_) => {
let newChatHistory: ChatMessageType[] = [];
data.forEach(
(chatItem: {
intermediate_steps?: "string";
is_bot: boolean;
message: string;
type: string;
files?: Array<any>;
}) => {
if (chatItem.message) {
newChatHistory.push(
chatItem.files
? {
isSend: !chatItem.is_bot,
message: chatItem.message,
thought: chatItem.intermediate_steps,
files: chatItem.files,
}
: {
isSend: !chatItem.is_bot,
message: chatItem.message,
thought: chatItem.intermediate_steps,
}
);
}
}
);
return newChatHistory;
});
}
if (data.type === "start") {
addChatHistory("", false);
isStream = true;
}
if (data.type === "end") {
if (data.message) {
updateLastMessage({ str: data.message, end: true });
}
if (data.intermediate_steps) {
updateLastMessage({
str: data.message,
thought: data.intermediate_steps,
end: true,
});
}
if (data.files) {
updateLastMessage({
end: true,
files: data.files,
});
}
setLockChat(false);
isStream = false;
}
if (data.type === "stream" && isStream) {
updateLastMessage({ str: data.message });
}
}
function connectWS() {
try {
const urlWs = getWebSocketUrl(
id.current,
process.env.NODE_ENV === "development"
);
const newWs = new WebSocket(urlWs);
newWs.onopen = () => {
console.log("WebSocket connection established!");
};
newWs.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log("Received data:", data);
handleWsMessage(data);
//get chat history
};
newWs.onclose = (event) => {
handleOnClose(event);
};
newWs.onerror = (ev) => {
getHealth()
.then((res) => {
if (res.status === 200) {
connectWS();
}
})
.catch((err) => {
setErrorData({
// message when the backend failed
title: "The backend is not responding. Please try again later.",
// possible solution list
list: [
"Check your internet connection.",
"Check if the backend is running.",
],
});
});
};
ws.current = newWs;
} catch (error) {
connectWS();
console.log(error);
}
}
useEffect(() => {
connectWS();
return () => {
console.log("unmount");
console.log(ws);
if (ws.current) {
ws.current.close();
}
};
}, []);
useEffect(() => {
if (
ws.current &&
(ws.current.readyState === ws.current.CLOSED ||
ws.current.readyState === ws.current.CLOSING)
) {
connectWS();
setLockChat(false);
}
}, [lockChat]);
async function sendAll(data: sendAllProps) {
try {
if (ws) {
ws.current.send(JSON.stringify(data));
}
} catch (error) {
setErrorData({
title: "There was an error sending the message",
list: [error.message],
});
setChatValue(data.message);
connectWS();
}
}
useEffect(() => {
if (ref.current) ref.current.scrollIntoView({ behavior: "smooth" });
}, [chatHistory]);
const ref = useRef(null);
useEffect(() => {
if (open && ref.current) {
ref.current.focus();
}
}, [open]);
function sendMessage() {
if (chatValue !== "") {
let nodeValidationErrors = validateNodes(reactFlowInstance);
if (nodeValidationErrors.length === 0) {
setLockChat(true);
let message = chatValue;
setChatValue("");
addChatHistory(message, true);
sendAll({
...reactFlowInstance.toObject(),
message,
chatHistory,
name: flow.name,
description: flow.description,
});
} else {
setErrorData({
title: "Oops! Looks like you missed some required information:",
list: nodeValidationErrors,
});
}
} else {
setErrorData({
title: "Error sending message",
list: ["The message cannot be empty."],
});
}
}
function clearChat() {
setChatHistory([]);
ws.current.send(JSON.stringify({ clear_history: true }));
if (lockChat) setLockChat(false);
}
function setModalOpen(x: boolean) {
setOpen(x);
}
return (
<Transition.Root show={open} appear={open} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
onClose={setModalOpen}
initialFocus={ref}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="send-message-modal-transition" />
</Transition.Child>
<div className="chat-modal-box">
<div className="chat-modal-box-div">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className=" chat-modal-dialog-panel">
<div className="chat-modal-dialog-panel-div">
<button
onClick={() => clearChat()}
className="chat-modal-dialog-trash-panel"
>
<Eraser className="h-4 w-4" />
</button>
<button
onClick={() => setModalOpen(false)}
className="chat-modal-dialog-x-panel"
>
<X className="h-5 w-5" />
</button>
</div>
<div ref={messagesRef} className="chat-modal-dialog-history">
{chatHistory.length > 0 ? (
chatHistory.map((c, i) => (
<ChatMessage
lockChat={lockChat}
chat={c}
lastMessage={chatHistory.length - 1 == i ? true : false}
key={i}
/>
))
) : (
<div className="chat-modal-dialog-span-box">
<span>
👋{" "}
<span className="text-lg text-muted-foreground">
Langflow Chat
</span>
</span>
<br />
<div className="chat-modal-dialog-desc">
<span className="text-base text-ring">
Start a conversation and click the agents thoughts{" "}
<span>
<MessagesSquare className="mx-1 inline h-5 w-5 animate-bounce " />
</span>{" "}
to inspect the chaining process.
</span>
</div>
</div>
)}
<div ref={ref}></div>
</div>
<div className="chat-modal-input-div">
<div className="chat-modal-input">
<ChatInput
chatValue={chatValue}
lockChat={lockChat}
sendMessage={sendMessage}
setChatValue={setChatValue}
inputRef={ref}
/>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
);
}

View file

@ -1,15 +1,16 @@
import { useContext, useEffect, useRef, useState } from "react";
// organize-imports-ignore
import { useContext, useRef, useState } from "react";
import { PopUpContext } from "../../contexts/popUpContext";
import AceEditor from "react-ace";
import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/mode-python";
import "ace-builds/src-noconflict/theme-github";
import "ace-builds/src-noconflict/theme-twilight";
import "ace-builds/src-noconflict/ext-language_tools";
import "ace-builds/src-noconflict/ace";
// import "ace-builds/webpack-resolver";
import { darkContext } from "../../contexts/darkContext";
import { postCustomComponent, postValidateCode } from "../../controllers/API";
import { alertContext } from "../../contexts/alertContext";
import { TerminalSquare } from "lucide-react";
import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
@ -19,9 +20,10 @@ import {
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { CODE_PROMPT_DIALOG_SUBTITLE } from "../../constants";
import { TerminalSquare } from "lucide-react";
import { alertContext } from "../../contexts/alertContext";
import { darkContext } from "../../contexts/darkContext";
import { postValidateCode } from "../../controllers/API";
import { APIClassType } from "../../types/api";
import {
Tabs,

View file

@ -1,8 +1,8 @@
import { Download } from "lucide-react";
import { useContext, useRef, useState } from "react";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { removeApiKeys } from "../../utils";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox";
import {
Dialog,
DialogContent,
@ -12,11 +12,11 @@ import {
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { Checkbox } from "../../components/ui/checkbox";
import { EXPORT_DIALOG_SUBTITLE } from "../../constants";
import { Download } from "lucide-react";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import { removeApiKeys } from "../../utils";
export default function ExportModal() {
const [open, setOpen] = useState(true);

View file

@ -1,7 +1,7 @@
import { Settings2 } from "lucide-react";
import { useContext, useRef, useState } from "react";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { Button } from "../../components/ui/button";
import {
Dialog,
DialogContent,
@ -11,11 +11,10 @@ import {
DialogTitle,
DialogTrigger,
} from "../../components/ui/dialog";
import { Button } from "../../components/ui/button";
import { SETTINGS_DIALOG_SUBTITLE } from "../../constants";
import EditFlowSettings from "../../components/EditFlowSettingsComponent";
import { Settings2 } from "lucide-react";
import { updateFlowInDatabase } from "../../controllers/API";
import { alertContext } from "../../contexts/alertContext";
import { PopUpContext } from "../../contexts/popUpContext";
import { TabsContext } from "../../contexts/tabsContext";
export default function FlowSettingsModal() {
const [open, setOpen] = useState(true);

View file

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

Some files were not shown because too many files have changed in this diff Show more