merge fix

This commit is contained in:
cristhianzl 2024-03-29 17:52:09 -03:00
commit 3a612c874c
89 changed files with 1296 additions and 1059 deletions

View file

@ -62,4 +62,6 @@ jobs:
context: . context: .
push: true push: true
file: ./build_and_push.Dockerfile file: ./build_and_push.Dockerfile
tags: logspace/langflow:${{ steps.check-version.outputs.version }} tags: |
logspace/langflow:${{ steps.check-version.outputs.version }}
logspace/langflow:latest-dev

View file

@ -0,0 +1,98 @@
# A new chapter for Langflow
# First things first
Thank you all for being part of the Langflow community. The journey so far has been amazing and we are happy to have you with us.
We have some exciting news to share with you. Langflow is changing, and we want to tell you all about it.
## Where have we been?
We spent the last few months working on a new version of Langflow. We wanted to make it more powerful, more flexible, and easier to use.
We're moving from version 0.6 straight to 1.0 (preview). This is a big change, and we want to explain why we're doing it and what it means for you.
## Why?
In the past year, we learned a lot from the community and our users. We saw the potential of Langflow and the need for a more powerful and flexible tool for building conversational AI applications (and beyond).
We realized that Langflow was hiding things from you that would really help you build better and more complex conversational AI applications. So we decided to make a big change.
## The only way to go is forward
From all the people we talked to, we learned that the most important thing for (most of) them is to have a tool that is easy to use, but also powerful and controllable. They also told us that Langflow's transparency could be improved.
In those points, we saw an opportunity to make Langflow much more powerful and flexible, while also making it easier to use and understand.
One key change you'll notice is that projects now require you to define Inputs and Outputs.
This is a big change, but it's also a big improvement.
It allows you to define the structure of your conversation and the data that flows through it.
This makes it easier to understand and control your conversation.
This change comes with a new way of visualizing your projects. Before 1.0 you would connect Components to ultimately build one final Component that was processed behind the scenes.
Now, each step of the process is defined by you, is visible on the canvas, and can be monitored and controlled by you. This makes it so that Composition is now just another way of building in Langflow. **Now data flows through your project more transparently**.
The caveat is existing projects may need some new Components to get them back to their full functionality.
[We've made this as easy as possible](../migration/compatibility), and there will be improvements to it as we get feedback in our Discord server and on GitHub.
## Custom Interactions
The moment we decided to make this change, we saw the potential to make Langflow even more yours.
By having a clear definition of Inputs and Outputs, we could build the experience around that which led us to create the **Interaction Panel**.
When building a project testing and debugging is crucial. The Interaction Panel is a tool that changes dynamically based on the Inputs and Outputs you defined in your project.
For example, let's say you are building a simple RAG application. Generally, you have an Input, some references that come from a Vector Store Search, a Prompt and the answer.
Now, you could plug the output of your Prompt into a [Text Output](../components/outputs#Text-Output), rename that to "Prompt Result" and see the output of your Prompt in the Interaction Panel.
{/* Add image here of the described above */}
This is just one example of how the Interaction Panel can help you build and debug your projects.
We have many planned features for the Interaction Panel, and we're excited to see how you use it and what you think of it.
## An easier start
The experience for the first-time user is also something we wanted to improve.
Meet the new and improved **New Project** screen. It's now easier to start a new project, and you can choose from a list of starter projects to get you started.
{/* Add new project image */}
We wanted to create start projects that would help you learn about new features and also give you a head start on your projects.
For now, we have:
- **Basic Prompting**: A simple project that shows you how to use the Prompt Component.
- **Data Ingestion**: A project that shows you how to ingest files into a Vector Store.
- **RAG**: A project that shows you how to use a Vector Store Search and a Prompt to build a simple RAG application.
As always, your feedback is invaluable, so please let us know what you think of the new starter projects and what you would like to see in the future.
## Less is more
We added many new Components to Langflow and updated some of the existing ones, and we will deprecate some of them.
The idea is that Langflow has evolved, and we want to make sure that the Components you use are the best they can be.
Some of them don't work well with the others, and some of them are just not needed anymore.
We are working on a list of Components that will be deprecated.
In the preview stages of 1.0, we will have a smaller list of Components so that we make sure that the ones we have are the best they can be.
Regardless, community feedback is very important in this matter, so please let us know what you think of the new Components and which ones you miss.
We are aiming at having a more stable and reliable set of Components that helps you get quickly to useful results.
This also means that your contributions in the [Langflow Store](https://langflow.store) and throughout the community are more important than ever.
## What's next?
Langflow went through a big change, and we are excited to see how you use it and what you think of it.
We plan to add more types of Input and Output like Image and Audio, and we also plan to add more Components to help you build more complex projects.
We also have some experimental features like a State Management System (so cool!) and a new way of building Grouped Components that we are excited to show you.
## Reach out
One last time, we want to thank you for being part of the Langflow community. Your feedback is invaluable, and we want to hear from you.

360
poetry.lock generated
View file

@ -602,7 +602,7 @@ name = "build"
version = "1.1.1" version = "1.1.1"
description = "A simple, correct Python build frontend" description = "A simple, correct Python build frontend"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">=3.8"
files = [ files = [
{file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"}, {file = "build-1.1.1-py3-none-any.whl", hash = "sha256:8ed0851ee76e6e38adce47e4bee3b51c771d86c64cf578d0c2245567ee200e73"},
{file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"}, {file = "build-1.1.1.tar.gz", hash = "sha256:8eea65bb45b1aac2e734ba2cc8dad3a6d97d97901a395bd0ed3e7b46953d2a31"},
@ -617,8 +617,9 @@ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
[package.extras] [package.extras]
docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"] docs = ["furo (>=2023.08.17)", "sphinx (>=7.0,<8.0)", "sphinx-argparse-cli (>=1.5)", "sphinx-autodoc-typehints (>=1.10)", "sphinx-issues (>=3.0.0)"]
test = ["filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"] test = ["build[uv,virtualenv]", "filelock (>=3)", "pytest (>=6.2.4)", "pytest-cov (>=2.12)", "pytest-mock (>=2)", "pytest-rerunfailures (>=9.1)", "pytest-xdist (>=1.34)", "setuptools (>=42.0.0)", "setuptools (>=56.0.0)", "setuptools (>=56.0.0)", "setuptools (>=67.8.0)", "wheel (>=0.36.0)"]
typing = ["importlib-metadata (>=5.1)", "mypy (>=1.5.0,<1.6.0)", "tomli", "typing-extensions (>=3.7.4.3)"] typing = ["build[uv]", "importlib-metadata (>=5.1)", "mypy (>=1.9.0,<1.10.0)", "tomli", "typing-extensions (>=3.7.4.3)"]
uv = ["uv (>=0.1.18)"]
virtualenv = ["virtualenv (>=20.0.35)"] virtualenv = ["virtualenv (>=20.0.35)"]
[[package]] [[package]]
@ -2584,9 +2585,9 @@ files = [
[package.dependencies] [package.dependencies]
google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0.dev0" google-api-core = ">=1.31.5,<2.0.dev0 || >2.3.0,<3.0.0.dev0"
google-auth = ">=1.19.0,<3.0.0.dev0" google-auth = ">=1.32.0,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0.dev0"
google-auth-httplib2 = ">=0.1.0" google-auth-httplib2 = ">=0.2.0,<1.0.0"
httplib2 = ">=0.15.0,<1.dev0" httplib2 = ">=0.19.0,<1.dev0"
uritemplate = ">=3.0.1,<5" uritemplate = ">=3.0.1,<5"
[[package]] [[package]]
@ -3338,13 +3339,13 @@ typer = ">=0.9.0,<0.10.0"
[[package]] [[package]]
name = "ipykernel" name = "ipykernel"
version = "6.29.3" version = "6.29.4"
description = "IPython Kernel for Jupyter" description = "IPython Kernel for Jupyter"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "ipykernel-6.29.3-py3-none-any.whl", hash = "sha256:5aa086a4175b0229d4eca211e181fb473ea78ffd9869af36ba7694c947302a21"}, {file = "ipykernel-6.29.4-py3-none-any.whl", hash = "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da"},
{file = "ipykernel-6.29.3.tar.gz", hash = "sha256:e14c250d1f9ea3989490225cc1a542781b095a18a19447fcf2b5eaf7d0ac5bd2"}, {file = "ipykernel-6.29.4.tar.gz", hash = "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c"},
] ]
[package.dependencies] [package.dependencies]
@ -3884,6 +3885,23 @@ langchain-core = ">=0.1.28,<0.2.0"
[package.extras] [package.extras]
extended-testing = ["lxml (>=5.1.0,<6.0.0)"] extended-testing = ["lxml (>=5.1.0,<6.0.0)"]
[[package]]
name = "langchain-text-splitters"
version = "0.0.1"
description = "LangChain text splitting utilities"
optional = false
python-versions = ">=3.8.1,<4.0"
files = [
{file = "langchain_text_splitters-0.0.1-py3-none-any.whl", hash = "sha256:f5b802f873f5ff6a8b9259ff34d53ed989666ef4e1582e6d1adb3b5520e3839a"},
{file = "langchain_text_splitters-0.0.1.tar.gz", hash = "sha256:ac459fa98799f5117ad5425a9330b21961321e30bc19a2a2f9f761ddadd62aa1"},
]
[package.dependencies]
langchain-core = ">=0.1.28,<0.2.0"
[package.extras]
extended-testing = ["lxml (>=5.1.0,<6.0.0)"]
[[package]] [[package]]
name = "langdetect" name = "langdetect"
version = "1.0.9" version = "1.0.9"
@ -5451,18 +5469,18 @@ datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"]
[[package]] [[package]]
name = "opentelemetry-api" name = "opentelemetry-api"
version = "1.23.0" version = "1.24.0"
description = "OpenTelemetry Python API" description = "OpenTelemetry Python API"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_api-1.23.0-py3-none-any.whl", hash = "sha256:cc03ea4025353048aadb9c64919099663664672ea1c6be6ddd8fee8e4cd5e774"}, {file = "opentelemetry_api-1.24.0-py3-none-any.whl", hash = "sha256:0f2c363d98d10d1ce93330015ca7fd3a65f60be64e05e30f557c61de52c80ca2"},
{file = "opentelemetry_api-1.23.0.tar.gz", hash = "sha256:14a766548c8dd2eb4dfc349739eb4c3893712a0daa996e5dbf945f9da665da9d"}, {file = "opentelemetry_api-1.24.0.tar.gz", hash = "sha256:42719f10ce7b5a9a73b10a4baf620574fb8ad495a9cbe5c18d76b75d8689c67e"},
] ]
[package.dependencies] [package.dependencies]
deprecated = ">=1.2.6" deprecated = ">=1.2.6"
importlib-metadata = ">=6.0,<7.0" importlib-metadata = ">=6.0,<=7.0"
[[package]] [[package]]
name = "opentelemetry-exporter-otlp" name = "opentelemetry-exporter-otlp"
@ -5481,27 +5499,27 @@ opentelemetry-exporter-otlp-proto-http = "1.23.0"
[[package]] [[package]]
name = "opentelemetry-exporter-otlp-proto-common" name = "opentelemetry-exporter-otlp-proto-common"
version = "1.23.0" version = "1.24.0"
description = "OpenTelemetry Protobuf encoding" description = "OpenTelemetry Protobuf encoding"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_exporter_otlp_proto_common-1.23.0-py3-none-any.whl", hash = "sha256:2a9e7e9d5a8b026b572684b6b24dcdefcaa58613d5ce3d644130b0c373c056c1"}, {file = "opentelemetry_exporter_otlp_proto_common-1.24.0-py3-none-any.whl", hash = "sha256:e51f2c9735054d598ad2df5d3eca830fecfb5b0bda0a2fa742c9c7718e12f641"},
{file = "opentelemetry_exporter_otlp_proto_common-1.23.0.tar.gz", hash = "sha256:35e4ea909e7a0b24235bd0aaf17fba49676527feb1823b46565ff246d5a1ab18"}, {file = "opentelemetry_exporter_otlp_proto_common-1.24.0.tar.gz", hash = "sha256:5d31fa1ff976cacc38be1ec4e3279a3f88435c75b38b1f7a099a1faffc302461"},
] ]
[package.dependencies] [package.dependencies]
opentelemetry-proto = "1.23.0" opentelemetry-proto = "1.24.0"
[[package]] [[package]]
name = "opentelemetry-exporter-otlp-proto-grpc" name = "opentelemetry-exporter-otlp-proto-grpc"
version = "1.23.0" version = "1.24.0"
description = "OpenTelemetry Collector Protobuf over gRPC Exporter" description = "OpenTelemetry Collector Protobuf over gRPC Exporter"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_exporter_otlp_proto_grpc-1.23.0-py3-none-any.whl", hash = "sha256:40f9e3e7761eb34f2a1001f4543028783ac26e2db27e420d5374f2cca0182dad"}, {file = "opentelemetry_exporter_otlp_proto_grpc-1.24.0-py3-none-any.whl", hash = "sha256:f40d62aa30a0a43cc1657428e59fcf82ad5f7ea8fff75de0f9d9cb6f739e0a3b"},
{file = "opentelemetry_exporter_otlp_proto_grpc-1.23.0.tar.gz", hash = "sha256:aa1a012eea5342bfef51fcf3f7f22601dcb0f0984a07ffe6025b2fbb6d91a2a9"}, {file = "opentelemetry_exporter_otlp_proto_grpc-1.24.0.tar.gz", hash = "sha256:217c6e30634f2c9797999ea9da29f7300479a94a610139b9df17433f915e7baa"},
] ]
[package.dependencies] [package.dependencies]
@ -5509,9 +5527,9 @@ deprecated = ">=1.2.6"
googleapis-common-protos = ">=1.52,<2.0" googleapis-common-protos = ">=1.52,<2.0"
grpcio = ">=1.0.0,<2.0.0" grpcio = ">=1.0.0,<2.0.0"
opentelemetry-api = ">=1.15,<2.0" opentelemetry-api = ">=1.15,<2.0"
opentelemetry-exporter-otlp-proto-common = "1.23.0" opentelemetry-exporter-otlp-proto-common = "1.24.0"
opentelemetry-proto = "1.23.0" opentelemetry-proto = "1.24.0"
opentelemetry-sdk = ">=1.23.0,<1.24.0" opentelemetry-sdk = ">=1.24.0,<1.25.0"
[package.extras] [package.extras]
test = ["pytest-grpc"] test = ["pytest-grpc"]
@ -5541,13 +5559,13 @@ test = ["responses (>=0.22.0,<0.25)"]
[[package]] [[package]]
name = "opentelemetry-instrumentation" name = "opentelemetry-instrumentation"
version = "0.44b0" version = "0.45b0"
description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python" description = "Instrumentation Tools & Auto Instrumentation for OpenTelemetry Python"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_instrumentation-0.44b0-py3-none-any.whl", hash = "sha256:79560f386425176bcc60c59190064597096114c4a8e5154f1cb281bb4e47d2fc"}, {file = "opentelemetry_instrumentation-0.45b0-py3-none-any.whl", hash = "sha256:06c02e2c952c1b076e8eaedf1b82f715e2937ba7eeacab55913dd434fbcec258"},
{file = "opentelemetry_instrumentation-0.44b0.tar.gz", hash = "sha256:8213d02d8c0987b9b26386ae3e091e0477d6331673123df736479322e1a50b48"}, {file = "opentelemetry_instrumentation-0.45b0.tar.gz", hash = "sha256:6c47120a7970bbeb458e6a73686ee9ba84b106329a79e4a4a66761f933709c7e"},
] ]
[package.dependencies] [package.dependencies]
@ -5557,47 +5575,45 @@ wrapt = ">=1.0.0,<2.0.0"
[[package]] [[package]]
name = "opentelemetry-instrumentation-asgi" name = "opentelemetry-instrumentation-asgi"
version = "0.44b0" version = "0.45b0"
description = "ASGI instrumentation for OpenTelemetry" description = "ASGI instrumentation for OpenTelemetry"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_instrumentation_asgi-0.44b0-py3-none-any.whl", hash = "sha256:0d95c84a8991008c8a8ac35e15d43cc7768a5bb46f95f129e802ad2990d7c366"}, {file = "opentelemetry_instrumentation_asgi-0.45b0-py3-none-any.whl", hash = "sha256:8be1157ed62f0db24e45fdf7933c530c4338bd025c5d4af7830e903c0756021b"},
{file = "opentelemetry_instrumentation_asgi-0.44b0.tar.gz", hash = "sha256:72d4d28ec7ccd551eac11edc5ae8cac3586c0a228467d6a95fad7b6d4edd597a"}, {file = "opentelemetry_instrumentation_asgi-0.45b0.tar.gz", hash = "sha256:97f55620f163fd3d20323e9fd8dc3aacc826c03397213ff36b877e0f4b6b08a6"},
] ]
[package.dependencies] [package.dependencies]
asgiref = ">=3.0,<4.0" asgiref = ">=3.0,<4.0"
opentelemetry-api = ">=1.12,<2.0" opentelemetry-api = ">=1.12,<2.0"
opentelemetry-instrumentation = "0.44b0" opentelemetry-instrumentation = "0.45b0"
opentelemetry-semantic-conventions = "0.44b0" opentelemetry-semantic-conventions = "0.45b0"
opentelemetry-util-http = "0.44b0" opentelemetry-util-http = "0.45b0"
[package.extras] [package.extras]
instruments = ["asgiref (>=3.0,<4.0)"] instruments = ["asgiref (>=3.0,<4.0)"]
test = ["opentelemetry-instrumentation-asgi[instruments]", "opentelemetry-test-utils (==0.44b0)"]
[[package]] [[package]]
name = "opentelemetry-instrumentation-fastapi" name = "opentelemetry-instrumentation-fastapi"
version = "0.44b0" version = "0.45b0"
description = "OpenTelemetry FastAPI Instrumentation" description = "OpenTelemetry FastAPI Instrumentation"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_instrumentation_fastapi-0.44b0-py3-none-any.whl", hash = "sha256:4441482944bea6676816668d56deb94af990e8c6e9582c581047e5d84c91d3c9"}, {file = "opentelemetry_instrumentation_fastapi-0.45b0-py3-none-any.whl", hash = "sha256:77d9c123a363129148f5f66d44094f3d67aaaa2b201396d94782b4a7f9ce4314"},
{file = "opentelemetry_instrumentation_fastapi-0.44b0.tar.gz", hash = "sha256:67ed10b93ad9d35238ae0be73cf8acbbb65a4a61fb7444d0aee5b0c492e294db"}, {file = "opentelemetry_instrumentation_fastapi-0.45b0.tar.gz", hash = "sha256:5a6b91e1c08a01601845fcfcfdefd0a2aecdb3c356d4a436a3210cb58c21487e"},
] ]
[package.dependencies] [package.dependencies]
opentelemetry-api = ">=1.12,<2.0" opentelemetry-api = ">=1.12,<2.0"
opentelemetry-instrumentation = "0.44b0" opentelemetry-instrumentation = "0.45b0"
opentelemetry-instrumentation-asgi = "0.44b0" opentelemetry-instrumentation-asgi = "0.45b0"
opentelemetry-semantic-conventions = "0.44b0" opentelemetry-semantic-conventions = "0.45b0"
opentelemetry-util-http = "0.44b0" opentelemetry-util-http = "0.45b0"
[package.extras] [package.extras]
instruments = ["fastapi (>=0.58,<1.0)"] instruments = ["fastapi (>=0.58,<1.0)"]
test = ["httpx (>=0.22,<1.0)", "opentelemetry-instrumentation-fastapi[instruments]", "opentelemetry-test-utils (==0.44b0)", "requests (>=2.23,<3.0)"]
[[package]] [[package]]
name = "opentelemetry-instrumentation-httpx" name = "opentelemetry-instrumentation-httpx"
@ -5622,13 +5638,13 @@ test = ["opentelemetry-instrumentation-httpx[instruments]", "opentelemetry-sdk (
[[package]] [[package]]
name = "opentelemetry-proto" name = "opentelemetry-proto"
version = "1.23.0" version = "1.24.0"
description = "OpenTelemetry Python Proto" description = "OpenTelemetry Python Proto"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_proto-1.23.0-py3-none-any.whl", hash = "sha256:4c017deca052cb287a6003b7c989ed8b47af65baeb5d57ebf93dde0793f78509"}, {file = "opentelemetry_proto-1.24.0-py3-none-any.whl", hash = "sha256:bcb80e1e78a003040db71ccf83f2ad2019273d1e0828089d183b18a1476527ce"},
{file = "opentelemetry_proto-1.23.0.tar.gz", hash = "sha256:e6aaf8b7ace8d021942d546161401b83eed90f9f2cc6f13275008cea730e4651"}, {file = "opentelemetry_proto-1.24.0.tar.gz", hash = "sha256:ff551b8ad63c6cabb1845ce217a6709358dfaba0f75ea1fa21a61ceddc78cab8"},
] ]
[package.dependencies] [package.dependencies]
@ -5636,40 +5652,40 @@ protobuf = ">=3.19,<5.0"
[[package]] [[package]]
name = "opentelemetry-sdk" name = "opentelemetry-sdk"
version = "1.23.0" version = "1.24.0"
description = "OpenTelemetry Python SDK" description = "OpenTelemetry Python SDK"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_sdk-1.23.0-py3-none-any.whl", hash = "sha256:a93c96990ac0f07c6d679e2f1015864ff7a4f5587122dd5af968034436efb1fd"}, {file = "opentelemetry_sdk-1.24.0-py3-none-any.whl", hash = "sha256:fa731e24efe832e98bcd90902085b359dcfef7d9c9c00eb5b9a18587dae3eb59"},
{file = "opentelemetry_sdk-1.23.0.tar.gz", hash = "sha256:9ddf60195837b59e72fd2033d6a47e2b59a0f74f0ec37d89387d89e3da8cab7f"}, {file = "opentelemetry_sdk-1.24.0.tar.gz", hash = "sha256:75bc0563affffa827700e0f4f4a68e1e257db0df13372344aebc6f8a64cde2e5"},
] ]
[package.dependencies] [package.dependencies]
opentelemetry-api = "1.23.0" opentelemetry-api = "1.24.0"
opentelemetry-semantic-conventions = "0.44b0" opentelemetry-semantic-conventions = "0.45b0"
typing-extensions = ">=3.7.4" typing-extensions = ">=3.7.4"
[[package]] [[package]]
name = "opentelemetry-semantic-conventions" name = "opentelemetry-semantic-conventions"
version = "0.44b0" version = "0.45b0"
description = "OpenTelemetry Semantic Conventions" description = "OpenTelemetry Semantic Conventions"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_semantic_conventions-0.44b0-py3-none-any.whl", hash = "sha256:7c434546c9cbd797ab980cc88bf9ff3f4a5a28f941117cad21694e43d5d92019"}, {file = "opentelemetry_semantic_conventions-0.45b0-py3-none-any.whl", hash = "sha256:a4a6fb9a7bacd9167c082aa4681009e9acdbfa28ffb2387af50c2fef3d30c864"},
{file = "opentelemetry_semantic_conventions-0.44b0.tar.gz", hash = "sha256:2e997cb28cd4ca81a25a9a43365f593d0c2b76be0685015349a89abdf1aa4ffa"}, {file = "opentelemetry_semantic_conventions-0.45b0.tar.gz", hash = "sha256:7c84215a44ac846bc4b8e32d5e78935c5c43482e491812a0bb8aaf87e4d92118"},
] ]
[[package]] [[package]]
name = "opentelemetry-util-http" name = "opentelemetry-util-http"
version = "0.44b0" version = "0.45b0"
description = "Web util for OpenTelemetry" description = "Web util for OpenTelemetry"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "opentelemetry_util_http-0.44b0-py3-none-any.whl", hash = "sha256:ff018ab6a2fa349537ff21adcef99a294248b599be53843c44f367aef6bccea5"}, {file = "opentelemetry_util_http-0.45b0-py3-none-any.whl", hash = "sha256:6628868b501b3004e1860f976f410eeb3d3499e009719d818000f24ce17b6e33"},
{file = "opentelemetry_util_http-0.44b0.tar.gz", hash = "sha256:75896dffcbbeb5df5429ad4526e22307fc041a27114e0c5bfd90bb219381e68f"}, {file = "opentelemetry_util_http-0.45b0.tar.gz", hash = "sha256:4ce08b6a7d52dd7c96b7705b5b4f06fdb6aa3eac1233b3b0bfef8a0cab9a92cd"},
] ]
[[package]] [[package]]
@ -6842,93 +6858,93 @@ windows-terminal = ["colorama (>=0.4.6)"]
[[package]] [[package]]
name = "pymongo" name = "pymongo"
version = "4.6.2" version = "4.6.3"
description = "Python driver for MongoDB <http://www.mongodb.org>" description = "Python driver for MongoDB <http://www.mongodb.org>"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "pymongo-4.6.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7640d176ee5b0afec76a1bda3684995cb731b2af7fcfd7c7ef8dc271c5d689af"}, {file = "pymongo-4.6.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e344d0afdd7c06c1f1e66a4736593293f432defc2191e6b411fc9c82fa8c5adc"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux1_i686.whl", hash = "sha256:4e2129ec8f72806751b621470ac5d26aaa18fae4194796621508fa0e6068278a"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux1_i686.whl", hash = "sha256:731a92dfc4022db763bfa835c6bd160f2d2cba6ada75749c2ed500e13983414b"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:c43205e85cbcbdf03cff62ad8f50426dd9d20134a915cfb626d805bab89a1844"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:c4726e36a2f7e92f09f5b8e92ba4db7525daffe31a0dcbcf0533edc0ade8c7d8"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux2014_i686.whl", hash = "sha256:91ddf95cedca12f115fbc5f442b841e81197d85aa3cc30b82aee3635a5208af2"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux2014_i686.whl", hash = "sha256:00e6cfce111883ca63a3c12878286e0b89871f4b840290e61fb6f88ee0e687be"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux2014_ppc64le.whl", hash = "sha256:0fbdbf2fba1b4f5f1522e9f11e21c306e095b59a83340a69e908f8ed9b450070"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux2014_ppc64le.whl", hash = "sha256:cc7a26edf79015c58eea46feb5b262cece55bc1d4929a8a9e0cbe7e6d6a9b0eb"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux2014_s390x.whl", hash = "sha256:097791d5a8d44e2444e0c8c4d6e14570ac11e22bcb833808885a5db081c3dc2a"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux2014_s390x.whl", hash = "sha256:4955be64d943b30f2a7ff98d818ca530f7cb37450bc6b32c37e0e74821907ef8"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:e0b208ebec3b47ee78a5c836e2e885e8c1e10f8ffd101aaec3d63997a4bdcd04"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux2014_x86_64.whl", hash = "sha256:af039afc6d787502c02089759778b550cb2f25dbe2780f5b050a2e37031c3fbf"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1849fd6f1917b4dc5dbf744b2f18e41e0538d08dd8e9ba9efa811c5149d665a3"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc15a7c7a99aed7d0831eaf78a607f1db0c7a255f96e3d18984231acd72f70c"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fa0bbbfbd1f8ebbd5facaa10f9f333b20027b240af012748555148943616fdf3"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8e97c138d811e9367723fcd07c4402a9211caae20479fdd6301d57762778a69f"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4522ad69a4ab0e1b46a8367d62ad3865b8cd54cf77518c157631dac1fdc97584"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebcc145c74d06296ce0cad35992185064e5cb2aadef719586778c144f0cd4d37"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:397949a9cc85e4a1452f80b7f7f2175d557237177120954eff00bf79553e89d3"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:664c64b6bdb31aceb80f0556951e5e2bf50d359270732268b4e7af00a1cf5d6c"},
{file = "pymongo-4.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d511db310f43222bc58d811037b176b4b88dc2b4617478c5ef01fea404f8601"}, {file = "pymongo-4.6.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4056bc421d4df2c61db4e584415f2b0f1eebb92cbf9222f7f38303467c37117"},
{file = "pymongo-4.6.2-cp310-cp310-win32.whl", hash = "sha256:991e406db5da4d89fb220a94d8caaf974ffe14ce6b095957bae9273c609784a0"}, {file = "pymongo-4.6.3-cp310-cp310-win32.whl", hash = "sha256:cdbea2aac1a4caa66ee912af3601557d2bda2f9f69feec83601c78c7e53ece64"},
{file = "pymongo-4.6.2-cp310-cp310-win_amd64.whl", hash = "sha256:94637941fe343000f728e28d3fe04f1f52aec6376b67b85583026ff8dab2a0e0"}, {file = "pymongo-4.6.3-cp310-cp310-win_amd64.whl", hash = "sha256:6cec7279e5a1b74b257d0270a8c97943d745811066630a6bc6beb413c68c6a33"},
{file = "pymongo-4.6.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:84593447a5c5fe7a59ba86b72c2c89d813fbac71c07757acdf162fbfd5d005b9"}, {file = "pymongo-4.6.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:138b9fa18d40401c217bc038a48bcde4160b02d36d8632015b1804971a2eaa2f"},
{file = "pymongo-4.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9aebddb2ec2128d5fc2fe3aee6319afef8697e0374f8a1fcca3449d6f625e7b4"}, {file = "pymongo-4.6.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60931b0e07448afe8866ffff764cd5bf4b1a855dc84c7dcb3974c6aa6a377a59"},
{file = "pymongo-4.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f706c1a644ed33eaea91df0a8fb687ce572b53eeb4ff9b89270cb0247e5d0e1"}, {file = "pymongo-4.6.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9b35f8bded43ff91475305445fedf0613f880ff7e25c75ae1028e1260a9b7a86"},
{file = "pymongo-4.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18c422e6b08fa370ed9d8670c67e78d01f50d6517cec4522aa8627014dfa38b6"}, {file = "pymongo-4.6.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:872bad5c83f7eec9da11e1fef5f858c6a4c79fe4a83c7780e7b0fe95d560ae3f"},
{file = "pymongo-4.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d002ae456a15b1d790a78bb84f87af21af1cb716a63efb2c446ab6bcbbc48ca"}, {file = "pymongo-4.6.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2ad3e5bfcd345c0bfe9af69a82d720860b5b043c1657ffb513c18a0dee19c19"},
{file = "pymongo-4.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9f86ba0c781b497a3c9c886765d7b6402a0e3ae079dd517365044c89cd7abb06"}, {file = "pymongo-4.6.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e208f2ab7b495eff8fd175022abfb0abce6307ac5aee3f4de51fc1a459b71c9"},
{file = "pymongo-4.6.2-cp311-cp311-win32.whl", hash = "sha256:ac20dd0c7b42555837c86f5ea46505f35af20a08b9cf5770cd1834288d8bd1b4"}, {file = "pymongo-4.6.3-cp311-cp311-win32.whl", hash = "sha256:4670edbb5ddd71a4d555668ef99b032a5f81b59e4145d66123aa0d831eac7883"},
{file = "pymongo-4.6.2-cp311-cp311-win_amd64.whl", hash = "sha256:e78af59fd0eb262c2a5f7c7d7e3b95e8596a75480d31087ca5f02f2d4c6acd19"}, {file = "pymongo-4.6.3-cp311-cp311-win_amd64.whl", hash = "sha256:1c2761302b6cbfd12e239ce1b8061d4cf424a361d199dcb32da534985cae9350"},
{file = "pymongo-4.6.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:6125f73503407792c8b3f80165f8ab88a4e448d7d9234c762681a4d0b446fcb4"}, {file = "pymongo-4.6.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:722f2b709b63311c0efda4fa4c603661faa4bec6bad24a6cc41a3bc6d841bf09"},
{file = "pymongo-4.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba052446a14bd714ec83ca4e77d0d97904f33cd046d7bb60712a6be25eb31dbb"}, {file = "pymongo-4.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:994386a4d6ad39e18bcede6dc8d1d693ec3ed897b88f86b1841fbc37227406da"},
{file = "pymongo-4.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2b65433c90e07dc252b4a55dfd885ca0df94b1cf77c5b8709953ec1983aadc03"}, {file = "pymongo-4.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:391aea047bba928006114282f175bc8d09c53fe1b7d8920bf888325e229302fe"},
{file = "pymongo-4.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2160d9c8cd20ce1f76a893f0daf7c0d38af093f36f1b5c9f3dcf3e08f7142814"}, {file = "pymongo-4.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4330c022024e7994b630199cdae909123e4b0e9cf15335de71b146c0f6a2435"},
{file = "pymongo-4.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f251f287e6d42daa3654b686ce1fcb6d74bf13b3907c3ae25954978c70f2cd4"}, {file = "pymongo-4.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01277a7e183c59081368e4efbde2b8f577014431b257959ca98d3a4e8682dd51"},
{file = "pymongo-4.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7d227a60b00925dd3aeae4675575af89c661a8e89a1f7d1677e57eba4a3693c"}, {file = "pymongo-4.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d30d5d7963453b478016bf7b0d87d7089ca24d93dbdecfbc9aa32f1b4772160a"},
{file = "pymongo-4.6.2-cp312-cp312-win32.whl", hash = "sha256:311794ef3ccae374aaef95792c36b0e5c06e8d5cf04a1bdb1b2bf14619ac881f"}, {file = "pymongo-4.6.3-cp312-cp312-win32.whl", hash = "sha256:a023804a3ac0f85d4510265b60978522368b5815772262e61e3a2222a8b315c9"},
{file = "pymongo-4.6.2-cp312-cp312-win_amd64.whl", hash = "sha256:f673b64a0884edcc56073bda0b363428dc1bf4eb1b5e7d0b689f7ec6173edad6"}, {file = "pymongo-4.6.3-cp312-cp312-win_amd64.whl", hash = "sha256:2a6ae9a600bbc2dbff719c98bf5da584fb8a4f2bb23729a09be2e9c3dbc61c8a"},
{file = "pymongo-4.6.2-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:fe010154dfa9e428bd2fb3e9325eff2216ab20a69ccbd6b5cac6785ca2989161"}, {file = "pymongo-4.6.3-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:3b909e5b1864de01510079b39bbdc480720c37747be5552b354bc73f02c24a3c"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:1f5f4cd2969197e25b67e24d5b8aa2452d381861d2791d06c493eaa0b9c9fcfe"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:48c60bd32ec141c0d45d8471179430003d9fb4490da181b8165fb1dce9cc255c"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:c9519c9d341983f3a1bd19628fecb1d72a48d8666cf344549879f2e63f54463b"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:36d7049fc183fe4edda3eae7f66ea14c660921429e082fe90b4b7f4dc6664a70"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c68bf4a399e37798f1b5aa4f6c02886188ef465f4ac0b305a607b7579413e366"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:18e5c161b18660f1c9d1f78236de45520a436be65e42b7bb51f25f74ad22bdde"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:a509db602462eb736666989739215b4b7d8f4bb8ac31d0bffd4be9eae96c63ef"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux2014_i686.whl", hash = "sha256:e458e6fc2b7dd40d15cda04898bd2d8c9ff7ae086c516bc261628d54eb4e3158"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:362a5adf6f3f938a8ff220a4c4aaa93e84ef932a409abecd837c617d17a5990f"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux2014_ppc64le.whl", hash = "sha256:e420e74c6db4594a6d09f39b58c0772679006cb0b4fc40901ba608794d87dad2"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:ee30a9d4c27a88042d0636aca0275788af09cc237ae365cd6ebb34524bddb9cc"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:9c9340c7161e112e36ebb97fbba1cdbe7db3dfacb694d2918b1f155a01f3d859"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:477914e13501bb1d4608339ee5bb618be056d2d0e7267727623516cfa902e652"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:26d036e0f5de09d0b21d0fc30314fcf2ae6359e4d43ae109aa6cf27b4ce02d30"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd343ca44982d480f1e39372c48e8e263fc6f32e9af2be456298f146a3db715"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7cf28d9c90e40d4e385b858e4095739829f466f23e08674085161d86bb4bb10"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3797e0a628534e07a36544d2bfa69e251a578c6d013e975e9e3ed2ac41f2d95"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9066dff9dc0a182478ca5885d0b8a2b820b462e19459ada109df7a3ced31b272"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:97d81d357e1a2a248b3494d52ebc8bf15d223ee89d59ee63becc434e07438a24"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1e1586ebdebe0447a24842480defac17c496430a218486c96e2da3f164c0f05"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed694c0d1977cb54281cb808bc2b247c17fb64b678a6352d3b77eb678ebe1bd9"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b3853fb66bf34ce1b6e573e1bbb3cb28763be9d1f57758535757faf1ab2f24a"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ceaaff4b812ae368cf9774989dea81b9bbb71e5bed666feca6a9f3087c03e49"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:462684a6f5ce6f2661c30eab4d1d459231e0eed280f338e716e31a24fc09ccb3"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7dd63f7c2b3727541f7f37d0fb78d9942eb12a866180fbeb898714420aad74e2"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0a4ea44e5a913bdb7c9abd34c69e9fcfac10dfaf49765463e0dc1ea922dd2a9d"},
{file = "pymongo-4.6.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e571434633f99a81e081738721bb38e697345281ed2f79c2f290f809ba3fbb2f"}, {file = "pymongo-4.6.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:098d420a8214ad25f872de7e8b309441995d12ece0376218a04d9ed5d2222cf3"},
{file = "pymongo-4.6.2-cp37-cp37m-win32.whl", hash = "sha256:3e9f6e2f3da0a6af854a3e959a6962b5f8b43bbb8113cd0bff0421c5059b3106"}, {file = "pymongo-4.6.3-cp37-cp37m-win32.whl", hash = "sha256:7330245253fbe2e09845069d2f4d35dd27f63e377034c94cb0ddac18bc8b0d82"},
{file = "pymongo-4.6.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3a5280f496297537301e78bde250c96fadf4945e7b2c397d8bb8921861dd236d"}, {file = "pymongo-4.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:151361c101600a85cb1c1e0db4e4b28318b521fcafa9b62d389f7342faaaee80"},
{file = "pymongo-4.6.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:5f6bcd2d012d82d25191a911a239fd05a8a72e8c5a7d81d056c0f3520cad14d1"}, {file = "pymongo-4.6.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:4d167d546352869125dc86f6fda6dffc627d8a9c8963eaee665825f2520d542b"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:4fa30494601a6271a8b416554bd7cde7b2a848230f0ec03e3f08d84565b4bf8c"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:eaf3d594ebfd5e1f3503d81e06a5d78e33cda27418b36c2491c3d4ad4fca5972"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:bea62f03a50f363265a7a651b4e2a4429b4f138c1864b2d83d4bf6f9851994be"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7ee79e02a7c5ed34706ecb5dad19e6c7d267cf86d28c075ef3127c58f3081279"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:b2d445f1cf147331947cc35ec10342f898329f29dd1947a3f8aeaf7e0e6878d1"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af5c5112db04cf62a5d9d224a24f289aaecb47d152c08a457cca81cee061d5bd"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:5db133d6ec7a4f7fc7e2bd098e4df23d7ad949f7be47b27b515c9fb9301c61e4"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux2014_i686.whl", hash = "sha256:6b5aec78aa4840e8d6c3881900259892ab5733a366696ca10d99d68c3d73eaaf"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:9eec7140cf7513aa770ea51505d312000c7416626a828de24318fdcc9ac3214c"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux2014_ppc64le.whl", hash = "sha256:9757602fb45c8ecc1883fe6db7c59c19d87eb3c645ec9342d28a6026837da931"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:5379ca6fd325387a34cda440aec2bd031b5ef0b0aa2e23b4981945cff1dab84c"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:dde9fb6e105ce054339256a8b7a9775212ebb29596ef4e402d7bbc63b354d202"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:579508536113dbd4c56e4738955a18847e8a6c41bf3c0b4ab18b51d81a6b7be8"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:7df8b166d3db6cfead4cf55b481408d8f0935d8bd8d6dbf64507c49ef82c7200"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3bae553ca39ed52db099d76acd5e8566096064dc7614c34c9359bb239ec4081"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53451190b8628e1ce7d1fe105dc376c3f10705127bd3b51fe3e107b9ff1851e6"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d0257e0eebb50f242ca28a92ef195889a6ad03dcdde5bf1c7ab9f38b7e810801"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:75107a386d4ccf5291e75cce8ca3898430e7907f4cc1208a17c9efad33a1ea84"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbafe3a1df21eeadb003c38fc02c1abf567648b6477ec50c4a3c042dca205371"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4a0660ce32d8459b7f12dc3ca0141528fead62d3cce31b548f96f30902074cc0"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aaecfafb407feb6f562c7f2f5b91f22bfacba6dd739116b1912788cff7124c4a"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa310096450e9c461b7dfd66cbc1c41771fe36c06200440bb3e062b1d4a06b6e"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e942945e9112075a84d2e2d6e0d0c98833cdcdfe48eb8952b917f996025c7ffa"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f465cca9b178e7bb782f952dd58e9e92f8ba056e585959465f2bb50feddef5f"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2f7b98f8d2cf3eeebde738d080ae9b4276d7250912d9751046a9ac1efc9b1ce2"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c67c19f653053ef2ebd7f1837c2978400058d6d7f66ec5760373a21eaf660158"},
{file = "pymongo-4.6.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:8110b78fc4b37dced85081d56795ecbee6a7937966e918e05e33a3900e8ea07d"}, {file = "pymongo-4.6.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c701de8e483fb5e53874aab642235361aac6de698146b02c644389eaa8c137b6"},
{file = "pymongo-4.6.2-cp38-cp38-win32.whl", hash = "sha256:df813f0c2c02281720ccce225edf39dc37855bf72cdfde6f789a1d1cf32ffb4b"}, {file = "pymongo-4.6.3-cp38-cp38-win32.whl", hash = "sha256:90525454546536544307e6da9c81f331a71a1b144e2d038fec587cc9f9250285"},
{file = "pymongo-4.6.2-cp38-cp38-win_amd64.whl", hash = "sha256:64ec3e2dcab9af61bdbfcb1dd863c70d1b0c220b8e8ac11df8b57f80ee0402b3"}, {file = "pymongo-4.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:3e1ba5a037c526a3f4060c28f8d45d71ed9626e2bf954b0cd9a8dcc3b45172ee"},
{file = "pymongo-4.6.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bff601fbfcecd2166d9a2b70777c2985cb9689e2befb3278d91f7f93a0456cae"}, {file = "pymongo-4.6.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:14a82593528cddc93cfea5ee78fac95ae763a3a4e124ca79ee0b24fbbc6da1c9"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:f1febca6f79e91feafc572906871805bd9c271b6a2d98a8bb5499b6ace0befed"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:cd6c15242d9306ff1748681c3235284cbe9f807aeaa86cd17d85e72af626e9a7"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:d788cb5cc947d78934be26eef1623c78cec3729dc93a30c23f049b361aa6d835"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6de33f1b2eed91b802ec7abeb92ffb981d052f3604b45588309aae9e0f6e3c02"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5c2f258489de12a65b81e1b803a531ee8cf633fa416ae84de65cd5f82d2ceb37"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0182899aafe830f25cf96c5976d724efeaaf7b6646c15424ad8dd25422b2efe1"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:fb24abcd50501b25d33a074c1790a1389b6460d2509e4b240d03fd2e5c79f463"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux2014_i686.whl", hash = "sha256:8d0ea740a2faa56f930dc82c5976d96c017ece26b29a1cddafb58721c7aab960"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:4d982c6db1da7cf3018183891883660ad085de97f21490d314385373f775915b"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux2014_ppc64le.whl", hash = "sha256:5c8a4982f5eb767c6fbfb8fb378683d09bcab7c3251ba64357eef600d43f6c23"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:b2dd8c874927a27995f64a3b44c890e8a944c98dec1ba79eab50e07f1e3f801b"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:becfa816545a48c8e740ac2fd624c1c121e1362072d68ffcf37a6b1be8ea187e"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:4993593de44c741d1e9f230f221fe623179f500765f9855936e4ff6f33571bad"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:ff7d1f449fcad23d9bc8e8dc2b9972be38bcd76d99ea5f7d29b2efa929c2a7ff"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:658f6c028edaeb02761ebcaca8d44d519c22594b2a51dcbc9bd2432aa93319e3"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e097f877de4d6af13a33ef938bf2a2350f424be5deabf8b857da95f5b080487a"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:68109c13176749fbbbbbdb94dd4a58dcc604db6ea43ee300b2602154aebdd55f"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:705a9bfd619301ee7e985d6f91f68b15dfcb2f6f36b8cc225cc82d4260d2bce5"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:707d28a822b918acf941cff590affaddb42a5d640614d71367c8956623a80cbc"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2ef1b4992ee1cb8bb16745e70afa0c02c5360220a7a8bb4775888721f052d0a6"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f251db26c239aec2a4d57fbe869e0a27b7f6b5384ec6bf54aeb4a6a5e7408234"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d10bdd46cbc35a2109737d36ffbef32e7420569a87904738ad444ccb7ac2c5"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57c05f2e310701fc17ae358caafd99b1830014e316f0242d13ab6c01db0ab1c2"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:17c1c143ba77d6e21fc8b48e93f0a5ed982a23447434e9ee4fbb6d633402506b"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b575fbe6396bbf21e4d0e5fd2e3cdb656dc90c930b6c5532192e9a89814f72d"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9e51e30d67b468a2a634ade928b30cb3e420127f148a9aec60de33f39087bdc4"},
{file = "pymongo-4.6.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ca5877754f3fa6e4fe5aacf5c404575f04c2d9efc8d22ed39576ed9098d555c8"}, {file = "pymongo-4.6.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:bec8e4e88984be157408f1923d25869e1b575c07711cdbdde596f66931800934"},
{file = "pymongo-4.6.2-cp39-cp39-win32.whl", hash = "sha256:8caa73fb19070008e851a589b744aaa38edd1366e2487284c61158c77fdf72af"}, {file = "pymongo-4.6.3-cp39-cp39-win32.whl", hash = "sha256:98877a9c4ad42df8253a12d8d17a3265781d1feb5c91c767bd153f88feb0b670"},
{file = "pymongo-4.6.2-cp39-cp39-win_amd64.whl", hash = "sha256:3e03c732cb64b96849310e1d8688fb70d75e2571385485bf2f1e7ad1d309fa53"}, {file = "pymongo-4.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:6d5b35da9e16cda630baed790ffc3d0d01029d269523a7cec34d2ec7e6823e75"},
{file = "pymongo-4.6.2.tar.gz", hash = "sha256:ab7d01ac832a1663dad592ccbd92bb0f0775bc8f98a1923c5e1a7d7fead495af"}, {file = "pymongo-4.6.3.tar.gz", hash = "sha256:400074090b9a631f120b42c61b222fd743490c133a5d2f99c0208cefcccc964e"},
] ]
[package.dependencies] [package.dependencies]
@ -8791,36 +8807,36 @@ files = [
[[package]] [[package]]
name = "torch" name = "torch"
version = "2.2.1" version = "2.2.2"
description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration" description = "Tensors and Dynamic neural networks in Python with strong GPU acceleration"
optional = true optional = true
python-versions = ">=3.8.0" python-versions = ">=3.8.0"
files = [ files = [
{file = "torch-2.2.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:8d3bad336dd2c93c6bcb3268e8e9876185bda50ebde325ef211fb565c7d15273"}, {file = "torch-2.2.2-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:bc889d311a855dd2dfd164daf8cc903a6b7273a747189cebafdd89106e4ad585"},
{file = "torch-2.2.1-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:5297f13370fdaca05959134b26a06a7f232ae254bf2e11a50eddec62525c9006"}, {file = "torch-2.2.2-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:15dffa4cc3261fa73d02f0ed25f5fa49ecc9e12bf1ae0a4c1e7a88bbfaad9030"},
{file = "torch-2.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:5f5dee8433798888ca1415055f5e3faf28a3bad660e4c29e1014acd3275ab11a"}, {file = "torch-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:11e8fe261233aeabd67696d6b993eeb0896faa175c6b41b9a6c9f0334bdad1c5"},
{file = "torch-2.2.1-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:b6d78338acabf1fb2e88bf4559d837d30230cf9c3e4337261f4d83200df1fcbe"}, {file = "torch-2.2.2-cp310-none-macosx_10_9_x86_64.whl", hash = "sha256:b2e2200b245bd9f263a0d41b6a2dab69c4aca635a01b30cca78064b0ef5b109e"},
{file = "torch-2.2.1-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:6ab3ea2e29d1aac962e905142bbe50943758f55292f1b4fdfb6f4792aae3323e"}, {file = "torch-2.2.2-cp310-none-macosx_11_0_arm64.whl", hash = "sha256:877b3e6593b5e00b35bbe111b7057464e76a7dd186a287280d941b564b0563c2"},
{file = "torch-2.2.1-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:d86664ec85902967d902e78272e97d1aff1d331f7619d398d3ffab1c9b8e9157"}, {file = "torch-2.2.2-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:ad4c03b786e074f46606f4151c0a1e3740268bcf29fbd2fdf6666d66341c1dcb"},
{file = "torch-2.2.1-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:d6227060f268894f92c61af0a44c0d8212e19cb98d05c20141c73312d923bc0a"}, {file = "torch-2.2.2-cp311-cp311-manylinux2014_aarch64.whl", hash = "sha256:32827fa1fbe5da8851686256b4cd94cc7b11be962862c2293811c94eea9457bf"},
{file = "torch-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:77e990af75fb1675490deb374d36e726f84732cd5677d16f19124934b2409ce9"}, {file = "torch-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:f9ef0a648310435511e76905f9b89612e45ef2c8b023bee294f5e6f7e73a3e7c"},
{file = "torch-2.2.1-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:46085e328d9b738c261f470231e987930f4cc9472d9ffb7087c7a1343826ac51"}, {file = "torch-2.2.2-cp311-none-macosx_10_9_x86_64.whl", hash = "sha256:95b9b44f3bcebd8b6cd8d37ec802048c872d9c567ba52c894bba90863a439059"},
{file = "torch-2.2.1-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:2d9e7e5ecbb002257cf98fae13003abbd620196c35f85c9e34c2adfb961321ec"}, {file = "torch-2.2.2-cp311-none-macosx_11_0_arm64.whl", hash = "sha256:49aa4126ede714c5aeef7ae92969b4b0bbe67f19665106463c39f22e0a1860d1"},
{file = "torch-2.2.1-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:ada53aebede1c89570e56861b08d12ba4518a1f8b82d467c32665ec4d1f4b3c8"}, {file = "torch-2.2.2-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:cf12cdb66c9c940227ad647bc9cf5dba7e8640772ae10dfe7569a0c1e2a28aca"},
{file = "torch-2.2.1-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:be21d4c41ecebed9e99430dac87de1439a8c7882faf23bba7fea3fea7b906ac1"}, {file = "torch-2.2.2-cp312-cp312-manylinux2014_aarch64.whl", hash = "sha256:89ddac2a8c1fb6569b90890955de0c34e1724f87431cacff4c1979b5f769203c"},
{file = "torch-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:79848f46196750367dcdf1d2132b722180b9d889571e14d579ae82d2f50596c5"}, {file = "torch-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:451331406b760f4b1ab298ddd536486ab3cfb1312614cfe0532133535be60bea"},
{file = "torch-2.2.1-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:7ee804847be6be0032fbd2d1e6742fea2814c92bebccb177f0d3b8e92b2d2b18"}, {file = "torch-2.2.2-cp312-none-macosx_10_9_x86_64.whl", hash = "sha256:eb4d6e9d3663e26cd27dc3ad266b34445a16b54908e74725adb241aa56987533"},
{file = "torch-2.2.1-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:84b2fb322ab091039fdfe74e17442ff046b258eb5e513a28093152c5b07325a7"}, {file = "torch-2.2.2-cp312-none-macosx_11_0_arm64.whl", hash = "sha256:bf9558da7d2bf7463390b3b2a61a6a3dbb0b45b161ee1dd5ec640bf579d479fc"},
{file = "torch-2.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5c0c83aa7d94569997f1f474595e808072d80b04d34912ce6f1a0e1c24b0c12a"}, {file = "torch-2.2.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:cd2bf7697c9e95fb5d97cc1d525486d8cf11a084c6af1345c2c2c22a6b0029d0"},
{file = "torch-2.2.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:91a1b598055ba06b2c386415d2e7f6ac818545e94c5def597a74754940188513"}, {file = "torch-2.2.2-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:b421448d194496e1114d87a8b8d6506bce949544e513742b097e2ab8f7efef32"},
{file = "torch-2.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f93ddf3001ecec16568390b507652644a3a103baa72de3ad3b9c530e3277098"}, {file = "torch-2.2.2-cp38-cp38-win_amd64.whl", hash = "sha256:3dbcd563a9b792161640c0cffe17e3270d85e8f4243b1f1ed19cca43d28d235b"},
{file = "torch-2.2.1-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:0e8bdd4c77ac2584f33ee14c6cd3b12767b4da508ec4eed109520be7212d1069"}, {file = "torch-2.2.2-cp38-none-macosx_10_9_x86_64.whl", hash = "sha256:31f4310210e7dda49f1fb52b0ec9e59382cfcb938693f6d5378f25b43d7c1d29"},
{file = "torch-2.2.1-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:6a21bcd7076677c97ca7db7506d683e4e9db137e8420eb4a68fb67c3668232a7"}, {file = "torch-2.2.2-cp38-none-macosx_11_0_arm64.whl", hash = "sha256:c795feb7e8ce2e0ef63f75f8e1ab52e7fd5e1a4d7d0c31367ade1e3de35c9e95"},
{file = "torch-2.2.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f1b90ac61f862634039265cd0f746cc9879feee03ff962c803486301b778714b"}, {file = "torch-2.2.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:a6e5770d68158d07456bfcb5318b173886f579fdfbf747543901ce718ea94782"},
{file = "torch-2.2.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:ed9e29eb94cd493b36bca9cb0b1fd7f06a0688215ad1e4b3ab4931726e0ec092"}, {file = "torch-2.2.2-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:67dcd726edff108e2cd6c51ff0e416fd260c869904de95750e80051358680d24"},
{file = "torch-2.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:c47bc25744c743f3835831a20efdcfd60aeb7c3f9804a213f61e45803d16c2a5"}, {file = "torch-2.2.2-cp39-cp39-win_amd64.whl", hash = "sha256:539d5ef6c4ce15bd3bd47a7b4a6e7c10d49d4d21c0baaa87c7d2ef8698632dfb"},
{file = "torch-2.2.1-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:0952549bcb43448c8d860d5e3e947dd18cbab491b14638e21750cb3090d5ad3e"}, {file = "torch-2.2.2-cp39-none-macosx_10_9_x86_64.whl", hash = "sha256:dff696de90d6f6d1e8200e9892861fd4677306d0ef604cb18f2134186f719f82"},
{file = "torch-2.2.1-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:26bd2272ec46fc62dcf7d24b2fb284d44fcb7be9d529ebf336b9860350d674ed"}, {file = "torch-2.2.2-cp39-none-macosx_11_0_arm64.whl", hash = "sha256:3a4dd910663fd7a124c056c878a52c2b0be4a5a424188058fe97109d4436ee42"},
] ]
[package.dependencies] [package.dependencies]
@ -9631,22 +9647,24 @@ files = [
[[package]] [[package]]
name = "weaviate-client" name = "weaviate-client"
version = "3.26.2" version = "4.5.4"
description = "A python native Weaviate client" description = "A python native Weaviate client"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "weaviate-client-3.26.2.tar.gz", hash = "sha256:63ec70839b64909810a64aa7b3e5b85088462e93c7e2ed3c32ebefb702f36723"}, {file = "weaviate-client-4.5.4.tar.gz", hash = "sha256:fc53dc73cd53df453c5e6dc758e49a6a1549212d6670ddd013392107120692f8"},
{file = "weaviate_client-3.26.2-py3-none-any.whl", hash = "sha256:ca43bfb9c06b8ae3fd938dc9158acd93d4cbf4622192e173333e1ff63cf97164"}, {file = "weaviate_client-4.5.4-py3-none-any.whl", hash = "sha256:f6d3a6b759e5aa0d3350067490526ea38b9274ae4043b4a3ae0064c28d56883f"},
] ]
[package.dependencies] [package.dependencies]
authlib = ">=1.2.1,<2.0.0" authlib = ">=1.2.1,<2.0.0"
grpcio = ">=1.57.0,<2.0.0"
grpcio-health-checking = ">=1.57.0,<2.0.0"
grpcio-tools = ">=1.57.0,<2.0.0"
httpx = "0.27.0"
pydantic = ">=2.5.0,<3.0.0"
requests = ">=2.30.0,<3.0.0" requests = ">=2.30.0,<3.0.0"
validators = ">=0.21.2,<1.0.0" validators = "0.22.0"
[package.extras]
grpc = ["grpcio (>=1.57.0,<2.0.0)", "grpcio-tools (>=1.57.0,<2.0.0)"]
[[package]] [[package]]
name = "websocket-client" name = "websocket-client"

View file

@ -7,7 +7,6 @@ maintainers = [
"Carlos Coelho <carlos@logspace.ai>", "Carlos Coelho <carlos@logspace.ai>",
"Cristhian Zanforlin <cristhian.lousa@gmail.com>", "Cristhian Zanforlin <cristhian.lousa@gmail.com>",
"Gabriel Almeida <gabriel@logspace.ai>", "Gabriel Almeida <gabriel@logspace.ai>",
"Gustavo Schaedler <gustavopoa@gmail.com>",
"Igor Carvalho <igorr.ackerman@gmail.com>", "Igor Carvalho <igorr.ackerman@gmail.com>",
"Lucas Eduoli <lucaseduoli@gmail.com>", "Lucas Eduoli <lucaseduoli@gmail.com>",
"Otávio Anovazzi <otavio2204@gmail.com>", "Otávio Anovazzi <otavio2204@gmail.com>",

View file

@ -26,13 +26,13 @@ def upgrade() -> None:
flow_constraints = inspector.get_unique_constraints("flow") flow_constraints = inspector.get_unique_constraints("flow")
user_constraints = inspector.get_unique_constraints("user") user_constraints = inspector.get_unique_constraints("user")
try: try:
if not any(constraint["name"] == "uq_apikey_id" for constraint in api_key_constraints): if not any(constraint["column_names"] == ["id"] for constraint in api_key_constraints):
with op.batch_alter_table("apikey", schema=None) as batch_op: with op.batch_alter_table("apikey", schema=None) as batch_op:
batch_op.create_unique_constraint("uq_apikey_id", ["id"]) batch_op.create_unique_constraint("uq_apikey_id", ["id"])
if not any(constraint["name"] == "uq_flow_id" for constraint in flow_constraints): if not any(constraint["column_names"] == ["id"] for constraint in flow_constraints):
with op.batch_alter_table("flow", schema=None) as batch_op: with op.batch_alter_table("flow", schema=None) as batch_op:
batch_op.create_unique_constraint("uq_flow_id", ["id"]) batch_op.create_unique_constraint("uq_flow_id", ["id"])
if not any(constraint["name"] == "uq_user_id" for constraint in user_constraints): if not any(constraint["column_names"] == ["id"] for constraint in user_constraints):
with op.batch_alter_table("user", schema=None) as batch_op: with op.batch_alter_table("user", schema=None) as batch_op:
batch_op.create_unique_constraint("uq_user_id", ["id"]) batch_op.create_unique_constraint("uq_user_id", ["id"])
except Exception as e: except Exception as e:

View file

@ -2,6 +2,7 @@ import warnings
from typing import Optional, Union from typing import Optional, Union
from langflow.field_typing import Text from langflow.field_typing import Text
from langflow.helpers.record import records_to_text
from langflow.interface.custom.custom_component import CustomComponent from langflow.interface.custom.custom_component import CustomComponent
from langflow.memory import add_messages from langflow.memory import add_messages
from langflow.schema import Record from langflow.schema import Record
@ -21,6 +22,7 @@ class ChatComponent(CustomComponent):
"sender": { "sender": {
"options": ["Machine", "User"], "options": ["Machine", "User"],
"display_name": "Sender Type", "display_name": "Sender Type",
"advanced": True,
}, },
"sender_name": {"display_name": "Sender Name"}, "sender_name": {"display_name": "Sender Name"},
"session_id": { "session_id": {
@ -31,6 +33,13 @@ class ChatComponent(CustomComponent):
"return_record": { "return_record": {
"display_name": "Return Record", "display_name": "Return Record",
"info": "Return the message as a record containing the sender, sender_name, and session_id.", "info": "Return the message as a record containing the sender, sender_name, and session_id.",
"advanced": True,
},
"record_template": {
"display_name": "Record Template",
"multiline": True,
"info": "In case of Message being a Record, this template will be used to convert it to text.",
"advanced": True,
}, },
} }
@ -74,9 +83,10 @@ class ChatComponent(CustomComponent):
self, self,
sender: Optional[str] = "User", sender: Optional[str] = "User",
sender_name: Optional[str] = "User", sender_name: Optional[str] = "User",
input_value: Optional[str] = None, input_value: Optional[Union[str, Record]] = None,
session_id: Optional[str] = None, session_id: Optional[str] = None,
return_record: Optional[bool] = False, return_record: Optional[bool] = False,
record_template: Optional[str] = "Text: {text}\nData: {data}",
) -> Union[Text, Record]: ) -> Union[Text, Record]:
input_value_record: Optional[Record] = None input_value_record: Optional[Record] = None
if return_record: if return_record:
@ -94,6 +104,8 @@ class ChatComponent(CustomComponent):
"session_id": session_id, "session_id": session_id,
}, },
) )
elif isinstance(input_value, Record):
input_value = records_to_text(template=record_template, records=input_value)
if not input_value: if not input_value:
input_value = "" input_value = ""
if return_record and input_value_record: if return_record and input_value_record:

View file

@ -1,18 +1,28 @@
from typing import Optional from typing import Optional, Union
from langflow.field_typing import Text from langflow.field_typing import Text
from langflow.helpers.record import records_to_text
from langflow.interface.custom.custom_component import CustomComponent from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema.schema import Record
class TextComponent(CustomComponent): class TextComponent(CustomComponent):
display_name = "Text Component" display_name = "Text Component"
description = "Used to pass text to the next component." description = "Used to pass text to the next component."
field_config = { def build_config(self):
"input_value": {"display_name": "Value", "multiline": True}, return {
} "input_value": {"display_name": "Value", "input_types": ["Record"], "info": "Text or Record to be passed."},
"record_template": {"display_name": "Record Template", "multiline": True},
}
def build(self, input_value: Optional[str] = "") -> Text: def build(
self,
input_value: Optional[Union[Text, Record]] = "",
record_template: Optional[str] = "Text: {text}\nData: {data}",
) -> Text:
if isinstance(input_value, Record):
input_value = records_to_text(template=record_template, records=input_value)
self.status = input_value self.status = input_value
if not input_value: if not input_value:
input_value = "" input_value = ""

View file

@ -1,18 +1,17 @@
__all__ = [ __all__ = [
"agents", "agents",
"chains", "chains",
"data",
"documentloaders", "documentloaders",
"embeddings", "embeddings",
"experimental", "experimental",
"helpers",
"inputs", "inputs",
"memories", "memories",
"model_specs", "model_specs",
"models",
"outputs", "outputs",
"retrievers", "retrievers",
"textsplitters", "textsplitters",
"toolkits", "toolkits",
"tools",
"vectorsearch",
"vectorstores", "vectorstores",
] ]

View file

@ -5,6 +5,7 @@ from .OpenAIConversationalAgent import ConversationalAgent
from .SQLAgent import SQLAgentComponent from .SQLAgent import SQLAgentComponent
from .VectorStoreAgent import VectorStoreAgentComponent from .VectorStoreAgent import VectorStoreAgentComponent
from .VectorStoreRouterAgent import VectorStoreRouterAgentComponent from .VectorStoreRouterAgent import VectorStoreRouterAgentComponent
from .XMLAgent import XMLAgentComponent
__all__ = [ __all__ = [
"AgentInitializerComponent", "AgentInitializerComponent",
@ -14,4 +15,5 @@ __all__ = [
"SQLAgentComponent", "SQLAgentComponent",
"VectorStoreAgentComponent", "VectorStoreAgentComponent",
"VectorStoreRouterAgentComponent", "VectorStoreRouterAgentComponent",
"XMLAgentComponent",
] ]

View file

@ -10,11 +10,11 @@ from langflow.schema import Record
class APIRequest(CustomComponent): class APIRequest(CustomComponent):
display_name: str = "API Request" display_name: str = "API Request"
description: str = "Make an HTTP request to the given URL." description: str = "Make HTTP requests given one or more URLs."
output_types: list[str] = ["Record"] output_types: list[str] = ["Record"]
documentation: str = "https://docs.langflow.org/components/utilities#api-request" documentation: str = "https://docs.langflow.org/components/utilities#api-request"
field_config = { field_config = {
"urls": {"display_name": "URLs", "info": "The URLs to make the request to."}, "urls": {"display_name": "URLs", "info": "URLs to make requests to."},
"method": { "method": {
"display_name": "Method", "display_name": "Method",
"info": "The HTTP method to use.", "info": "The HTTP method to use.",

View file

@ -7,7 +7,7 @@ from langflow.schema import Record
class DirectoryComponent(CustomComponent): class DirectoryComponent(CustomComponent):
display_name = "Directory" display_name = "Directory"
description = "Load Text Files from a Directory and Convert Them to Records." description = "Recursively load files from a directory."
def build_config(self) -> Dict[str, Any]: def build_config(self) -> Dict[str, Any]:
return { return {

View file

@ -1,4 +1,5 @@
from typing import Any, Dict, List from pathlib import Path
from typing import Any, Dict
from langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record from langflow.base.data.utils import TEXT_FILE_TYPES, parse_text_file_to_record
from langflow.interface.custom.custom_component import CustomComponent from langflow.interface.custom.custom_component import CustomComponent
@ -7,12 +8,12 @@ from langflow.schema import Record
class FileComponent(CustomComponent): class FileComponent(CustomComponent):
display_name = "Files" display_name = "Files"
description = "Read Text Files" description = "A generic file loader."
def build_config(self) -> Dict[str, Any]: def build_config(self) -> Dict[str, Any]:
return { return {
"paths": { "path": {
"display_name": "Paths", "display_name": "Path",
"field_type": "file", "field_type": "file",
"file_types": TEXT_FILE_TYPES, "file_types": TEXT_FILE_TYPES,
"info": f"Supported file types: {', '.join(TEXT_FILE_TYPES)}", "info": f"Supported file types: {', '.join(TEXT_FILE_TYPES)}",
@ -26,7 +27,8 @@ class FileComponent(CustomComponent):
def load_file(self, path: str, silent_errors: bool = False) -> Record: def load_file(self, path: str, silent_errors: bool = False) -> Record:
resolved_path = self.resolve_path(path) resolved_path = self.resolve_path(path)
extension = resolved_path.split(".")[-1] path_obj = Path(resolved_path)
extension = path_obj.suffix[1:].lower()
if extension == "doc": if extension == "doc":
raise ValueError("doc files are not supported. Please save as .docx") raise ValueError("doc files are not supported. Please save as .docx")
if extension not in TEXT_FILE_TYPES: if extension not in TEXT_FILE_TYPES:
@ -37,9 +39,9 @@ class FileComponent(CustomComponent):
def build( def build(
self, self,
paths: List[str], path: str,
silent_errors: bool = False, silent_errors: bool = False,
) -> List[Record]: ) -> Record:
records = [self.load_file(path, silent_errors) for path in paths] record = self.load_file(path, silent_errors)
self.status = records self.status = record
return records return record

View file

@ -1,117 +0,0 @@
from typing import List
from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record
from langflow.utils.constants import LOADERS_INFO
class FileLoaderComponent(CustomComponent):
display_name: str = "File Loader"
description: str = "Generic File Loader"
def build_config(self):
loader_options = ["Automatic"] + [loader_info["name"] for loader_info in LOADERS_INFO]
file_types = []
suffixes = []
for loader_info in LOADERS_INFO:
if "allowedTypes" in loader_info:
file_types.extend(loader_info["allowedTypes"])
suffixes.extend([f".{ext}" for ext in loader_info["allowedTypes"]])
return {
"file_path": {
"display_name": "File Path",
"required": True,
"field_type": "file",
"file_types": [
"json",
"txt",
"csv",
"jsonl",
"html",
"htm",
"conllu",
"enex",
"msg",
"pdf",
"srt",
"eml",
"md",
"mdx",
"pptx",
"docx",
],
"suffixes": [
".json",
".txt",
".csv",
".jsonl",
".html",
".htm",
".conllu",
".enex",
".msg",
".pdf",
".srt",
".eml",
".md",
".mdx",
".pptx",
".docx",
],
# "file_types" : file_types,
# "suffixes": suffixes,
},
"loader": {
"display_name": "Loader",
"is_list": True,
"required": True,
"options": loader_options,
"value": "Automatic",
},
"code": {"show": False},
}
def build(self, file_path: str, loader: str) -> List[Record]:
file_type = file_path.split(".")[-1]
# Map the loader to the correct loader class
selected_loader_info = None
for loader_info in LOADERS_INFO:
if loader_info["name"] == loader:
selected_loader_info = loader_info
break
if selected_loader_info is None and loader != "Automatic":
raise ValueError(f"Loader {loader} not found in the loader info list")
if loader == "Automatic":
# Determine the loader based on the file type
default_loader_info = None
for info in LOADERS_INFO:
if "defaultFor" in info and file_type in info["defaultFor"]:
default_loader_info = info
break
if default_loader_info is None:
raise ValueError(f"No default loader found for file type: {file_type}")
selected_loader_info = default_loader_info
if isinstance(selected_loader_info, dict):
loader_import: str = selected_loader_info["import"]
else:
raise ValueError(f"Loader info for {loader} is not a dict\nLoader info:\n{selected_loader_info}")
module_name, class_name = loader_import.rsplit(".", 1)
try:
# Import the loader class
loader_module = __import__(module_name, fromlist=[class_name])
loader_instance = getattr(loader_module, class_name)
except ImportError as e:
raise ValueError(f"Loader {loader} could not be imported\nLoader info:\n{selected_loader_info}") from e
result = loader_instance(file_path=file_path)
docs = result.load()
return self.to_records(docs)

View file

@ -8,7 +8,7 @@ from langflow.schema import Record
class URLComponent(CustomComponent): class URLComponent(CustomComponent):
display_name = "URL" display_name = "URL"
description = "Load URLs and convert them to records." description = "Fetch text content given one or more URLs."
def build_config(self) -> Dict[str, Any]: def build_config(self) -> Dict[str, Any]:
return { return {
@ -22,4 +22,5 @@ class URLComponent(CustomComponent):
loader = WebBaseLoader(web_paths=urls) loader = WebBaseLoader(web_paths=urls)
docs = loader.load() docs = loader.load()
records = self.to_records(docs) records = self.to_records(docs)
self.status = records
return records return records

View file

@ -1,7 +1,7 @@
from .APIRequest import APIRequest from .APIRequest import APIRequest
from .Directory import DirectoryComponent from .Directory import DirectoryComponent
from .File import FileComponent from .File import FileComponent
from .FileLoader import FileLoaderComponent
from .URL import URLComponent from .URL import URLComponent
__all__ = ["APIRequest", "DirectoryComponent", "FileComponent", "FileLoaderComponent", "URLComponent"] __all__ = ["APIRequest", "DirectoryComponent", "FileComponent", "URLComponent"]

View file

@ -2,7 +2,7 @@ from typing import Optional
from langchain_community.embeddings.cohere import CohereEmbeddings from langchain_community.embeddings.cohere import CohereEmbeddings
from langflow.interface.custom.custom_component import CustomComponent from langflow.custom import CustomComponent
class CohereEmbeddingsComponent(CustomComponent): class CohereEmbeddingsComponent(CustomComponent):

View file

@ -1,23 +1,27 @@
from .ClearMessageHistory import ClearMessageHistoryComponent from .ClearMessageHistory import ClearMessageHistoryComponent
from .ExtractDataFromRecord import ExtractKeyFromRecordComponent from .ExtractDataFromRecord import ExtractKeyFromRecordComponent
from .Listen import ListenComponent from .FlowTool import FlowToolComponent
from .ListFlows import ListFlowsComponent from .ListFlows import ListFlowsComponent
from .Listen import ListenComponent
from .MergeRecords import MergeRecordsComponent from .MergeRecords import MergeRecordsComponent
from .Notify import NotifyComponent from .Notify import NotifyComponent
from .PythonFunction import PythonFunctionComponent
from .RunFlow import RunFlowComponent from .RunFlow import RunFlowComponent
from .RunnableExecutor import RunnableExecComponent from .RunnableExecutor import RunnableExecComponent
from .SQLExecutor import SQLExecutorComponent from .SQLExecutor import SQLExecutorComponent
from .SubFlow import SubFlowComponent
__all__ = [ __all__ = [
"ClearMessageHistoryComponent", "ClearMessageHistoryComponent",
"ExtractKeyFromRecordComponent", "ExtractKeyFromRecordComponent",
"ListenComponent", "FlowToolComponent",
"ListFlowsComponent", "ListFlowsComponent",
"ListenComponent",
"MergeRecordsComponent", "MergeRecordsComponent",
"MessageHistoryComponent",
"NotifyComponent", "NotifyComponent",
"PythonFunctionComponent",
"RunFlowComponent", "RunFlowComponent",
"RunnableExecComponent", "RunnableExecComponent",
"SQLExecutorComponent", "SQLExecutorComponent",
"TextToRecordComponent", "SubFlowComponent",
] ]

View file

@ -2,16 +2,16 @@ from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record from langflow.schema import Record
class TextToRecordComponent(CustomComponent): class CreateRecordComponent(CustomComponent):
display_name = "Text to Record" display_name = "Create Record"
description = "A component to create a record from Text." description = "A component to create a record."
beta: bool = True beta: bool = True
def build_config(self): def build_config(self):
return { return {
"data": { "data": {
"display_name": "Data", "display_name": "Data",
"info": "The data to convert to a record.", "info": "Data to contruct the record.",
"input_types": ["Text"], "input_types": ["Text"],
} }
} }

View file

@ -7,8 +7,8 @@ from langflow.schema import Record
class DocumentToRecordComponent(CustomComponent): class DocumentToRecordComponent(CustomComponent):
display_name = "Documents to Records" display_name = "Documents To Records"
description = "Convert documents to records." description = "Convert LangChain Documents into Records."
field_config = { field_config = {
"documents": {"display_name": "Documents"}, "documents": {"display_name": "Documents"},

View file

@ -6,7 +6,7 @@ from langflow.interface.custom.custom_component import CustomComponent
class UUIDGeneratorComponent(CustomComponent): class UUIDGeneratorComponent(CustomComponent):
documentation: str = "http://docs.langflow.org/components/custom" documentation: str = "http://docs.langflow.org/components/custom"
display_name = "Unique ID Generator" display_name = "ID Generator"
description = "Generates a unique ID." description = "Generates a unique ID."
def update_build_config( def update_build_config(

View file

@ -7,7 +7,7 @@ from langflow.schema import Record
class MessageHistoryComponent(CustomComponent): class MessageHistoryComponent(CustomComponent):
display_name = "Message History" display_name = "Message History"
description = "Used to retrieve stored messages." description = "Used to retrieve stored chat messages."
beta: bool = True beta: bool = True
def build_config(self): def build_config(self):
@ -30,7 +30,7 @@ class MessageHistoryComponent(CustomComponent):
def build( def build(
self, self,
sender: Optional[str] = None, sender: Optional[str] = "Machine",
sender_name: Optional[str] = None, sender_name: Optional[str] = None,
session_id: Optional[str] = None, session_id: Optional[str] = None,
n_messages: int = 5, n_messages: int = 5,

View file

@ -4,9 +4,9 @@ from langflow.interface.custom.custom_component import CustomComponent
from langflow.schema import Record from langflow.schema import Record
class RecordsAsTextComponent(CustomComponent): class RecordsToTextComponent(CustomComponent):
display_name = "Records to Text" display_name = "Records To Text"
description = "Converts Records into single piece of text using a template." description = "Convert Records into plain text using a pre-defined template."
def build_config(self): def build_config(self):
return { return {

View file

@ -4,7 +4,7 @@ from langflow.schema import Record
class UpdateRecordComponent(CustomComponent): class UpdateRecordComponent(CustomComponent):
display_name = "Update Record" display_name = "Update Record"
description = "Updates a record with new data." description = "Updates a Record with new data. Akin to a Python dictionary update."
def build_config(self): def build_config(self):
return { return {

View file

@ -2,8 +2,6 @@ from .CustomComponent import Component
from .DocumentToRecord import DocumentToRecordComponent from .DocumentToRecord import DocumentToRecordComponent
from .IDGenerator import UUIDGeneratorComponent from .IDGenerator import UUIDGeneratorComponent
from .MessageHistory import MessageHistoryComponent from .MessageHistory import MessageHistoryComponent
from .PythonFunction import PythonFunctionComponent
from .RecordsAsText import RecordsAsTextComponent
from .TextToRecord import TextToRecordComponent from .TextToRecord import TextToRecordComponent
from .UpdateRecord import UpdateRecordComponent from .UpdateRecord import UpdateRecordComponent
@ -13,7 +11,7 @@ __all__ = [
"DocumentToRecordComponent", "DocumentToRecordComponent",
"UUIDGeneratorComponent", "UUIDGeneratorComponent",
"PythonFunctionComponent", "PythonFunctionComponent",
"RecordsAsTextComponent", "RecordsToTextComponent",
"TextToRecordComponent", "TextToRecordComponent",
"MessageHistoryComponent", "MessageHistoryComponent",
] ]

View file

@ -7,7 +7,7 @@ from langflow.schema import Record
class ChatInput(ChatComponent): class ChatInput(ChatComponent):
display_name = "Chat Input" display_name = "Chat Input"
description = "Used to get user input from the chat." description = "Capture user inputs from the chat interface."
icon = "ChatInput" icon = "ChatInput"
def build( def build(

View file

@ -1,30 +0,0 @@
import ast
import json
from langflow.custom import CustomComponent
from langflow.schema import Record
class JSONInputComponent(CustomComponent):
display_name = "JSON Input"
description = "Load a JSON object as input."
def build_config(self):
return {
"json_str": {
"display_name": "JSON String",
"multiline": True,
"info": "The JSON string to load.",
}
}
def build(self, json_str: str) -> Record:
try:
data = json.loads(json_str)
except json.JSONDecodeError:
try:
data = ast.literal_eval(json_str)
except (SyntaxError, ValueError):
raise ValueError("Invalid JSON string.")
record = Record(data=data)
return record

View file

@ -6,7 +6,7 @@ from langflow.interface.custom.custom_component import CustomComponent
class PromptComponent(CustomComponent): class PromptComponent(CustomComponent):
display_name: str = "Prompt" display_name: str = "Prompt"
description: str = "A component for creating prompts using templates" description: str = "A component for creating prompt templates using dynamic variables."
icon = "terminal-square" icon = "terminal-square"
def build_config(self): def build_config(self):

View file

@ -6,7 +6,21 @@ from langflow.field_typing import Text
class TextInput(TextComponent): class TextInput(TextComponent):
display_name = "Text Input" display_name = "Text Input"
description = "Used to pass text input to the next component." description = "Capture Text or Record and send text inputs."
def build(self, input_value: Optional[str] = "") -> Text: def build_config(self):
return super().build(input_value=input_value) return {
"input_value": {
"display_name": "Value",
"input_types": ["Record"],
"info": "Text or Record to be passed as input.",
},
"record_template": {"display_name": "Record Template", "multiline": True},
}
def build(
self,
input_value: Optional[str] = "",
record_template: Optional[str] = "{text}",
) -> Text:
return super().build(input_value=input_value, record_template=record_template)

View file

@ -2,4 +2,4 @@ from .ChatInput import ChatInput
from .Prompt import PromptComponent from .Prompt import PromptComponent
from .TextInput import TextInput from .TextInput import TextInput
__all__ = ["ChatInput", "TextInput", "PromptComponent"] __all__ = ["ChatInput", "PromptComponent", "TextInput"]

View file

@ -1,33 +0,0 @@
from typing import Dict, Optional
from langchain_community.llms.ctransformers import CTransformers
from langflow.interface.custom.custom_component import CustomComponent
class CTransformersComponent(CustomComponent):
display_name = "CTransformers"
description = "C Transformers LLM models"
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers"
def build_config(self):
return {
"model": {"display_name": "Model", "required": True},
"model_file": {
"display_name": "Model File",
"required": False,
"field_type": "file",
"file_types": [".bin"],
},
"model_type": {"display_name": "Model Type", "required": True},
"config": {
"display_name": "Config",
"advanced": True,
"required": False,
"field_type": "dict",
"value": '{"top_k":40,"top_p":0.95,"temperature":0.8,"repetition_penalty":1.1,"last_n_tokens":64,"seed":-1,"max_new_tokens":256,"stop":"","stream":"False","reset":"True","batch_size":8,"threads":-1,"context_length":-1,"gpu_layers":0}',
},
}
def build(self, model: str, model_file: str, model_type: str, config: Optional[Dict] = None) -> CTransformers:
return CTransformers(model=model, model_file=model_file, model_type=model_type, config=config) # type: ignore

View file

@ -3,8 +3,8 @@ from typing import Callable, Optional, Union
from langchain_community.chat_models.anthropic import ChatAnthropic from langchain_community.chat_models.anthropic import ChatAnthropic
from pydantic.v1.types import SecretStr from pydantic.v1.types import SecretStr
from langflow.custom import CustomComponent
from langflow.field_typing import BaseLanguageModel from langflow.field_typing import BaseLanguageModel
from langflow.interface.custom.custom_component import CustomComponent
class ChatAnthropicComponent(CustomComponent): class ChatAnthropicComponent(CustomComponent):
@ -20,31 +20,48 @@ class ChatAnthropicComponent(CustomComponent):
"field_type": "str", "field_type": "str",
"password": True, "password": True,
}, },
"anthropic_api_url": {
"display_name": "Anthropic API URL",
"field_type": "str",
},
"model_kwargs": { "model_kwargs": {
"display_name": "Model Kwargs", "display_name": "Model Kwargs",
"field_type": "dict", "field_type": "dict",
"advanced": True, "advanced": True,
}, },
"model_name": {
"display_name": "Model Name",
"field_type": "str",
"advanced": False,
"required": False,
"options": ["claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-haiku-20240307"],
},
"temperature": { "temperature": {
"display_name": "Temperature", "display_name": "Temperature",
"field_type": "float", "field_type": "float",
}, },
"max_tokens": {
"display_name": "Max Tokens",
"field_type": "int",
"advanced": False,
"required": False,
},
"top_k": {"display_name": "Top K", "field_type": "int", "advanced": True},
"top_p": {"display_name": "Top P", "field_type": "float", "advanced": True},
} }
def build( def build(
self, self,
anthropic_api_key: str, anthropic_api_key: str,
anthropic_api_url: Optional[str] = None,
model_kwargs: dict = {}, model_kwargs: dict = {},
model_name: str = "claude-3-opus-20240229",
temperature: Optional[float] = None, temperature: Optional[float] = None,
max_tokens: Optional[int] = 1024,
top_k: Optional[int] = None,
top_p: Optional[float] = None,
) -> Union[BaseLanguageModel, Callable]: ) -> Union[BaseLanguageModel, Callable]:
return ChatAnthropic( return ChatAnthropic(
anthropic_api_key=SecretStr(anthropic_api_key), anthropic_api_key=SecretStr(anthropic_api_key),
anthropic_api_url=anthropic_api_url,
model_kwargs=model_kwargs, model_kwargs=model_kwargs,
model_name=model_name,
temperature=temperature, temperature=temperature,
max_tokens=max_tokens, # type: ignore
top_k=top_k,
top_p=top_p,
) )

View file

@ -1,131 +0,0 @@
from typing import Any, Dict, List, Optional
from langchain_community.llms.llamacpp import LlamaCpp
from langflow.interface.custom.custom_component import CustomComponent
class LlamaCppComponent(CustomComponent):
display_name = "LlamaCpp"
description = "llama.cpp model."
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/llamacpp"
def build_config(self):
return {
"grammar": {"display_name": "Grammar", "advanced": True},
"cache": {"display_name": "Cache", "advanced": True},
"client": {"display_name": "Client", "advanced": True},
"echo": {"display_name": "Echo", "advanced": True},
"f16_kv": {"display_name": "F16 KV", "advanced": True},
"grammar_path": {"display_name": "Grammar Path", "advanced": True},
"last_n_tokens_size": {"display_name": "Last N Tokens Size", "advanced": True},
"logits_all": {"display_name": "Logits All", "advanced": True},
"logprobs": {"display_name": "Logprobs", "advanced": True},
"lora_base": {"display_name": "Lora Base", "advanced": True},
"lora_path": {"display_name": "Lora Path", "advanced": True},
"max_tokens": {"display_name": "Max Tokens", "advanced": True},
"metadata": {"display_name": "Metadata", "advanced": True},
"model_kwargs": {"display_name": "Model Kwargs", "advanced": True},
"model_path": {
"display_name": "Model Path",
"field_type": "file",
"file_types": [".bin"],
"required": True,
},
"n_batch": {"display_name": "N Batch", "advanced": True},
"n_ctx": {"display_name": "N Ctx", "advanced": True},
"n_gpu_layers": {"display_name": "N GPU Layers", "advanced": True},
"n_parts": {"display_name": "N Parts", "advanced": True},
"n_threads": {"display_name": "N Threads", "advanced": True},
"repeat_penalty": {"display_name": "Repeat Penalty", "advanced": True},
"rope_freq_base": {"display_name": "Rope Freq Base", "advanced": True},
"rope_freq_scale": {"display_name": "Rope Freq Scale", "advanced": True},
"seed": {"display_name": "Seed", "advanced": True},
"stop": {"display_name": "Stop", "advanced": True},
"streaming": {"display_name": "Streaming", "advanced": True},
"suffix": {"display_name": "Suffix", "advanced": True},
"tags": {"display_name": "Tags", "advanced": True},
"temperature": {"display_name": "Temperature"},
"top_k": {"display_name": "Top K", "advanced": True},
"top_p": {"display_name": "Top P", "advanced": True},
"use_mlock": {"display_name": "Use Mlock", "advanced": True},
"use_mmap": {"display_name": "Use Mmap", "advanced": True},
"verbose": {"display_name": "Verbose", "advanced": True},
"vocab_only": {"display_name": "Vocab Only", "advanced": True},
}
def build(
self,
model_path: str,
grammar: Optional[str] = None,
cache: Optional[bool] = None,
client: Optional[Any] = None,
echo: Optional[bool] = False,
f16_kv: bool = True,
grammar_path: Optional[str] = None,
last_n_tokens_size: Optional[int] = 64,
logits_all: bool = False,
logprobs: Optional[int] = None,
lora_base: Optional[str] = None,
lora_path: Optional[str] = None,
max_tokens: Optional[int] = 256,
metadata: Optional[Dict] = None,
model_kwargs: Dict = {},
n_batch: Optional[int] = 8,
n_ctx: int = 512,
n_gpu_layers: Optional[int] = 1,
n_parts: int = -1,
n_threads: Optional[int] = 1,
repeat_penalty: Optional[float] = 1.1,
rope_freq_base: float = 10000.0,
rope_freq_scale: float = 1.0,
seed: int = -1,
stop: Optional[List[str]] = [],
streaming: bool = True,
suffix: Optional[str] = "",
tags: Optional[List[str]] = [],
temperature: Optional[float] = 0.8,
top_k: Optional[int] = 40,
top_p: Optional[float] = 0.95,
use_mlock: bool = False,
use_mmap: Optional[bool] = True,
verbose: bool = True,
vocab_only: bool = False,
) -> LlamaCpp:
return LlamaCpp(
model_path=model_path,
grammar=grammar,
cache=cache,
client=client,
echo=echo,
f16_kv=f16_kv,
grammar_path=grammar_path,
last_n_tokens_size=last_n_tokens_size,
logits_all=logits_all,
logprobs=logprobs,
lora_base=lora_base,
lora_path=lora_path,
max_tokens=max_tokens,
metadata=metadata,
model_kwargs=model_kwargs,
n_batch=n_batch,
n_ctx=n_ctx,
n_gpu_layers=n_gpu_layers,
n_parts=n_parts,
n_threads=n_threads,
repeat_penalty=repeat_penalty,
rope_freq_base=rope_freq_base,
rope_freq_scale=rope_freq_scale,
seed=seed,
stop=stop,
streaming=streaming,
suffix=suffix,
tags=tags,
temperature=temperature,
top_k=top_k,
top_p=top_p,
use_mlock=use_mlock,
use_mmap=use_mmap,
verbose=verbose,
vocab_only=vocab_only,
)

View file

@ -4,7 +4,6 @@ from .AnthropicSpecs import AnthropicComponent
from .AzureChatOpenAISpecs import AzureChatOpenAISpecsComponent from .AzureChatOpenAISpecs import AzureChatOpenAISpecsComponent
from .BaiduQianfanChatEndpointsSpecs import QianfanChatEndpointComponent from .BaiduQianfanChatEndpointsSpecs import QianfanChatEndpointComponent
from .BaiduQianfanLLMEndpointsSpecs import QianfanLLMEndpointComponent from .BaiduQianfanLLMEndpointsSpecs import QianfanLLMEndpointComponent
from .CTransformersSpecs import CTransformersComponent
from .ChatAnthropicSpecs import ChatAnthropicComponent from .ChatAnthropicSpecs import ChatAnthropicComponent
from .ChatLiteLLMSpecs import ChatLiteLLMComponent from .ChatLiteLLMSpecs import ChatLiteLLMComponent
from .ChatOllamaEndpointSpecs import ChatOllamaComponent from .ChatOllamaEndpointSpecs import ChatOllamaComponent
@ -13,7 +12,6 @@ from .ChatVertexAISpecs import ChatVertexAIComponent
from .CohereSpecs import CohereComponent from .CohereSpecs import CohereComponent
from .GoogleGenerativeAISpecs import GoogleGenerativeAIComponent from .GoogleGenerativeAISpecs import GoogleGenerativeAIComponent
from .HuggingFaceEndpointsSpecs import HuggingFaceEndpointsComponent from .HuggingFaceEndpointsSpecs import HuggingFaceEndpointsComponent
from .LlamaCppSpecs import LlamaCppComponent
from .OllamaLLMSpecs import OllamaLLM from .OllamaLLMSpecs import OllamaLLM
from .VertexAISpecs import VertexAIComponent from .VertexAISpecs import VertexAIComponent
@ -24,7 +22,6 @@ __all__ = [
"AzureChatOpenAISpecsComponent", "AzureChatOpenAISpecsComponent",
"QianfanChatEndpointComponent", "QianfanChatEndpointComponent",
"QianfanLLMEndpointComponent", "QianfanLLMEndpointComponent",
"CTransformersComponent",
"ChatAnthropicComponent", "ChatAnthropicComponent",
"ChatLiteLLMComponent", "ChatLiteLLMComponent",
"ChatOllamaComponent", "ChatOllamaComponent",
@ -33,7 +30,6 @@ __all__ = [
"CohereComponent", "CohereComponent",
"GoogleGenerativeAIComponent", "GoogleGenerativeAIComponent",
"HuggingFaceEndpointsComponent", "HuggingFaceEndpointsComponent",
"LlamaCppComponent",
"OllamaLLM", "OllamaLLM",
"VertexAIComponent", "VertexAIComponent",
] ]

View file

@ -10,31 +10,50 @@ class AmazonBedrockComponent(LCModelComponent):
display_name: str = "Amazon Bedrock" display_name: str = "Amazon Bedrock"
description: str = "Generate text using LLM model from Amazon Bedrock." description: str = "Generate text using LLM model from Amazon Bedrock."
icon = "Amazon" icon = "Amazon"
field_order = [
"model_id",
"credentials_profile_name",
"region_name",
"model_kwargs",
"endpoint_url",
"cache",
"stream",
"input_value",
"system_message",
]
def build_config(self): def build_config(self):
return { return {
"model_id": { "model_id": {
"display_name": "Model Id", "display_name": "Model Id",
"options": [ "options": [
"ai21.j2-grande-instruct", "amazon.titan-text-express-v1",
"ai21.j2-jumbo-instruct", "amazon.titan-text-lite-v1",
"ai21.j2-mid", "amazon.titan-embed-text-v1",
"ai21.j2-mid-v1", "amazon.titan-embed-image-v1",
"ai21.j2-ultra", "amazon.titan-image-generator-v1",
"ai21.j2-ultra-v1",
"anthropic.claude-instant-v1",
"anthropic.claude-v1",
"anthropic.claude-v2", "anthropic.claude-v2",
"anthropic.claude-v2:1",
"anthropic.claude-3-sonnet-20240229-v1:0",
"anthropic.claude-3-haiku-20240307-v1:0",
"anthropic.claude-instant-v1",
"ai21.j2-mid-v1",
"ai21.j2-ultra-v1",
"cohere.command-text-v14", "cohere.command-text-v14",
"cohere.command-light-text-v14",
"cohere.embed-english-v3",
"cohere.embed-multilingual-v3",
"meta.llama2-13b-chat-v1",
"meta.llama2-70b-chat-v1",
"mistral.mistral-7b-instruct-v0:2",
"mistral.mixtral-8x7b-instruct-v0:1",
], ],
}, },
"credentials_profile_name": {"display_name": "Credentials Profile Name"}, "credentials_profile_name": {"display_name": "Credentials Profile Name"},
"streaming": {"display_name": "Streaming", "field_type": "bool"},
"endpoint_url": {"display_name": "Endpoint URL"}, "endpoint_url": {"display_name": "Endpoint URL"},
"region_name": {"display_name": "Region Name"}, "region_name": {"display_name": "Region Name"},
"model_kwargs": {"display_name": "Model Kwargs"}, "model_kwargs": {"display_name": "Model Kwargs"},
"cache": {"display_name": "Cache"}, "cache": {"display_name": "Cache"},
"code": {"advanced": True},
"input_value": {"display_name": "Input"}, "input_value": {"display_name": "Input"},
"system_message": {"display_name": "System Message", "info": "System message to pass to the model."}, "system_message": {"display_name": "System Message", "info": "System message to pass to the model."},
"stream": { "stream": {
@ -52,7 +71,6 @@ class AmazonBedrockComponent(LCModelComponent):
region_name: Optional[str] = None, region_name: Optional[str] = None,
model_kwargs: Optional[dict] = None, model_kwargs: Optional[dict] = None,
endpoint_url: Optional[str] = None, endpoint_url: Optional[str] = None,
streaming: bool = False,
cache: Optional[bool] = None, cache: Optional[bool] = None,
stream: bool = False, stream: bool = False,
) -> Text: ) -> Text:
@ -63,7 +81,7 @@ class AmazonBedrockComponent(LCModelComponent):
region_name=region_name, region_name=region_name,
model_kwargs=model_kwargs, model_kwargs=model_kwargs,
endpoint_url=endpoint_url, endpoint_url=endpoint_url,
streaming=streaming, streaming=stream,
cache=cache, cache=cache,
) # type: ignore ) # type: ignore
except Exception as e: except Exception as e:

View file

@ -17,15 +17,17 @@ class AnthropicLLM(LCModelComponent):
"model": { "model": {
"display_name": "Model Name", "display_name": "Model Name",
"options": [ "options": [
"claude-3-opus-20240229",
"claude-3-sonnet-20240229",
"claude-3-haiku-20240307",
"claude-2.1", "claude-2.1",
"claude-2.0", "claude-2.0",
"claude-instant-1.2", "claude-instant-1.2",
"claude-instant-1", "claude-instant-1",
# Add more models as needed
], ],
"info": "https://python.langchain.com/docs/integrations/chat/anthropic", "info": "https://python.langchain.com/docs/integrations/chat/anthropic",
"required": True, "required": True,
"value": "claude-2.1", "value": "claude-3-opus-20240229",
}, },
"anthropic_api_key": { "anthropic_api_key": {
"display_name": "Anthropic API Key", "display_name": "Anthropic API Key",
@ -43,8 +45,8 @@ class AnthropicLLM(LCModelComponent):
"field_type": "float", "field_type": "float",
"value": 0.7, "value": 0.7,
}, },
"api_endpoint": { "anthropic_api_url": {
"display_name": "API Endpoint", "display_name": "Anthropic API URL",
"info": "Endpoint of the Anthropic API. Defaults to 'https://api.anthropic.com' if not specified.", "info": "Endpoint of the Anthropic API. Defaults to 'https://api.anthropic.com' if not specified.",
}, },
"code": {"show": False}, "code": {"show": False},
@ -67,12 +69,12 @@ class AnthropicLLM(LCModelComponent):
anthropic_api_key: Optional[str] = None, anthropic_api_key: Optional[str] = None,
max_tokens: Optional[int] = None, max_tokens: Optional[int] = None,
temperature: Optional[float] = None, temperature: Optional[float] = None,
api_endpoint: Optional[str] = None, anthropic_api_url: Optional[str] = None,
stream: bool = False, stream: bool = False,
) -> Text: ) -> Text:
# Set default API endpoint if not provided # Set default API endpoint if not provided
if not api_endpoint: if not anthropic_api_url:
api_endpoint = "https://api.anthropic.com" anthropic_api_url = "https://api.anthropic.com"
try: try:
output = ChatAnthropic( output = ChatAnthropic(
@ -80,7 +82,7 @@ class AnthropicLLM(LCModelComponent):
anthropic_api_key=(SecretStr(anthropic_api_key) if anthropic_api_key else None), anthropic_api_key=(SecretStr(anthropic_api_key) if anthropic_api_key else None),
max_tokens_to_sample=max_tokens, # type: ignore max_tokens_to_sample=max_tokens, # type: ignore
temperature=temperature, temperature=temperature,
anthropic_api_url=api_endpoint, anthropic_api_url=anthropic_api_url,
) )
except Exception as e: except Exception as e:
raise ValueError("Could not connect to Anthropic API.") from e raise ValueError("Could not connect to Anthropic API.") from e

View file

@ -8,7 +8,7 @@ from langflow.field_typing import Text
class AzureChatOpenAIComponent(LCModelComponent): class AzureChatOpenAIComponent(LCModelComponent):
display_name: str = "AzureOpenAI" display_name: str = "Azure OpenAI"
description: str = "Generate text using LLM model from Azure OpenAI." description: str = "Generate text using LLM model from Azure OpenAI."
documentation: str = "https://python.langchain.com/docs/integrations/llms/azure_openai" documentation: str = "https://python.langchain.com/docs/integrations/llms/azure_openai"
beta = False beta = False

View file

@ -8,7 +8,7 @@ from langflow.field_typing import Text
class QianfanChatEndpointComponent(LCModelComponent): class QianfanChatEndpointComponent(LCModelComponent):
display_name: str = "QianfanChat" display_name: str = "Qianfan"
description: str = ( description: str = (
"Generate text using Baidu Qianfan chat models. Get more detail from " "Generate text using Baidu Qianfan chat models. Get more detail from "
"https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint." "https://python.langchain.com/docs/integrations/chat/baidu_qianfan_endpoint."

View file

@ -1,59 +0,0 @@
from typing import Dict, Optional
from langchain_community.llms.ctransformers import CTransformers
from langflow.base.models.model import LCModelComponent
from langflow.field_typing import Text
class CTransformersComponent(LCModelComponent):
display_name = "CTransformers"
description = "Generate text using CTransformers LLM models"
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/ctransformers"
def build_config(self):
return {
"model": {"display_name": "Model", "required": True},
"model_file": {
"display_name": "Model File",
"required": False,
"field_type": "file",
"file_types": [".bin"],
},
"model_type": {"display_name": "Model Type", "required": True},
"config": {
"display_name": "Config",
"advanced": True,
"required": False,
"field_type": "dict",
"value": '{"top_k":40,"top_p":0.95,"temperature":0.8,"repetition_penalty":1.1,"last_n_tokens":64,"seed":-1,"max_new_tokens":256,"stop":"","stream":"False","reset":"True","batch_size":8,"threads":-1,"context_length":-1,"gpu_layers":0}',
},
"input_value": {"display_name": "Input"},
"stream": {
"display_name": "Stream",
"info": "Stream the response from the model.",
},
"system_message": {
"display_name": "System Message",
"info": "System message to pass to the model.",
},
}
def build(
self,
model: str,
model_file: str,
input_value: Text,
model_type: str,
stream: bool = False,
config: Optional[Dict] = None,
) -> Text:
output = CTransformers(
client=None,
model=model,
model_file=model_file,
model_type=model_type,
config=config, # noqa
)
return self.get_result(runnable=output, stream=stream, input_value=input_value)

View file

@ -1,148 +0,0 @@
from typing import Any, Dict, List, Optional
from langchain_community.llms.llamacpp import LlamaCpp
from langflow.base.models.model import LCModelComponent
from langflow.field_typing import Text
class LlamaCppComponent(LCModelComponent):
display_name = "LlamaCpp"
description = "Generate text using llama.cpp model."
documentation = "https://python.langchain.com/docs/modules/model_io/models/llms/integrations/llamacpp"
def build_config(self):
return {
"grammar": {"display_name": "Grammar", "advanced": True},
"cache": {"display_name": "Cache", "advanced": True},
"client": {"display_name": "Client", "advanced": True},
"echo": {"display_name": "Echo", "advanced": True},
"f16_kv": {"display_name": "F16 KV", "advanced": True},
"grammar_path": {"display_name": "Grammar Path", "advanced": True},
"last_n_tokens_size": {
"display_name": "Last N Tokens Size",
"advanced": True,
},
"logits_all": {"display_name": "Logits All", "advanced": True},
"logprobs": {"display_name": "Logprobs", "advanced": True},
"lora_base": {"display_name": "Lora Base", "advanced": True},
"lora_path": {"display_name": "Lora Path", "advanced": True},
"max_tokens": {"display_name": "Max Tokens", "advanced": True},
"metadata": {"display_name": "Metadata", "advanced": True},
"model_kwargs": {"display_name": "Model Kwargs", "advanced": True},
"model_path": {
"display_name": "Model Path",
"field_type": "file",
"file_types": [".bin"],
"required": True,
},
"n_batch": {"display_name": "N Batch", "advanced": True},
"n_ctx": {"display_name": "N Ctx", "advanced": True},
"n_gpu_layers": {"display_name": "N GPU Layers", "advanced": True},
"n_parts": {"display_name": "N Parts", "advanced": True},
"n_threads": {"display_name": "N Threads", "advanced": True},
"repeat_penalty": {"display_name": "Repeat Penalty", "advanced": True},
"rope_freq_base": {"display_name": "Rope Freq Base", "advanced": True},
"rope_freq_scale": {"display_name": "Rope Freq Scale", "advanced": True},
"seed": {"display_name": "Seed", "advanced": True},
"stop": {"display_name": "Stop", "advanced": True},
"streaming": {"display_name": "Streaming", "advanced": True},
"suffix": {"display_name": "Suffix", "advanced": True},
"tags": {"display_name": "Tags", "advanced": True},
"temperature": {"display_name": "Temperature"},
"top_k": {"display_name": "Top K", "advanced": True},
"top_p": {"display_name": "Top P", "advanced": True},
"use_mlock": {"display_name": "Use Mlock", "advanced": True},
"use_mmap": {"display_name": "Use Mmap", "advanced": True},
"verbose": {"display_name": "Verbose", "advanced": True},
"vocab_only": {"display_name": "Vocab Only", "advanced": True},
"input_value": {"display_name": "Input"},
"stream": {
"display_name": "Stream",
"info": "Stream the response from the model.",
},
"system_message": {
"display_name": "System Message",
"info": "System message to pass to the model.",
},
}
def build(
self,
model_path: str,
input_value: Text,
grammar: Optional[str] = None,
cache: Optional[bool] = None,
client: Optional[Any] = None,
echo: Optional[bool] = False,
f16_kv: bool = True,
grammar_path: Optional[str] = None,
last_n_tokens_size: Optional[int] = 64,
logits_all: bool = False,
logprobs: Optional[int] = None,
lora_base: Optional[str] = None,
lora_path: Optional[str] = None,
max_tokens: Optional[int] = 256,
metadata: Optional[Dict] = None,
model_kwargs: Dict = {},
n_batch: Optional[int] = 8,
n_ctx: int = 512,
n_gpu_layers: Optional[int] = 1,
n_parts: int = -1,
n_threads: Optional[int] = 1,
repeat_penalty: Optional[float] = 1.1,
rope_freq_base: float = 10000.0,
rope_freq_scale: float = 1.0,
seed: int = -1,
stop: Optional[List[str]] = [],
streaming: bool = True,
suffix: Optional[str] = "",
tags: Optional[List[str]] = [],
temperature: Optional[float] = 0.8,
top_k: Optional[int] = 40,
top_p: Optional[float] = 0.95,
use_mlock: bool = False,
use_mmap: Optional[bool] = True,
verbose: bool = True,
vocab_only: bool = False,
stream: bool = False,
) -> Text:
output = LlamaCpp(
model_path=model_path,
grammar=grammar,
cache=cache,
client=client,
echo=echo,
f16_kv=f16_kv,
grammar_path=grammar_path,
last_n_tokens_size=last_n_tokens_size,
logits_all=logits_all,
logprobs=logprobs,
lora_base=lora_base,
lora_path=lora_path,
max_tokens=max_tokens,
metadata=metadata,
model_kwargs=model_kwargs,
n_batch=n_batch,
n_ctx=n_ctx,
n_gpu_layers=n_gpu_layers,
n_parts=n_parts,
n_threads=n_threads,
repeat_penalty=repeat_penalty,
rope_freq_base=rope_freq_base,
rope_freq_scale=rope_freq_scale,
seed=seed,
stop=stop,
streaming=streaming,
suffix=suffix,
tags=tags,
temperature=temperature,
top_k=top_k,
top_p=top_p,
use_mlock=use_mlock,
use_mmap=use_mmap,
verbose=verbose,
vocab_only=vocab_only,
)
return self.get_result(runnable=output, stream=stream, input_value=input_value)

View file

@ -13,7 +13,7 @@ from langflow.field_typing import Text
class ChatOllamaComponent(LCModelComponent): class ChatOllamaComponent(LCModelComponent):
display_name = "ChatOllama" display_name = "Ollama"
description = "Generate text using Local LLM for chat with Ollama." description = "Generate text using Local LLM for chat with Ollama."
icon = "Ollama" icon = "Ollama"

View file

@ -7,7 +7,7 @@ from langflow.field_typing import Text
class ChatVertexAIComponent(LCModelComponent): class ChatVertexAIComponent(LCModelComponent):
display_name = "ChatVertexAI" display_name = "Vertex AI"
description = "Generate text using Vertex AI Chat large language models API." description = "Generate text using Vertex AI Chat large language models API."
icon = "VertexAI" icon = "VertexAI"

View file

@ -2,11 +2,9 @@ from .AmazonBedrockModel import AmazonBedrockComponent
from .AnthropicModel import AnthropicLLM from .AnthropicModel import AnthropicLLM
from .AzureOpenAIModel import AzureChatOpenAIComponent from .AzureOpenAIModel import AzureChatOpenAIComponent
from .BaiduQianfanChatModel import QianfanChatEndpointComponent from .BaiduQianfanChatModel import QianfanChatEndpointComponent
from .CTransformersModel import CTransformersComponent
from .CohereModel import CohereComponent from .CohereModel import CohereComponent
from .GoogleGenerativeAIModel import GoogleGenerativeAIComponent from .GoogleGenerativeAIModel import GoogleGenerativeAIComponent
from .HuggingFaceModel import HuggingFaceEndpointsComponent from .HuggingFaceModel import HuggingFaceEndpointsComponent
from .LlamaCppModel import LlamaCppComponent
from .OllamaModel import ChatOllamaComponent from .OllamaModel import ChatOllamaComponent
from .OpenAIModel import OpenAIModelComponent from .OpenAIModel import OpenAIModelComponent
from .VertexAiModel import ChatVertexAIComponent from .VertexAiModel import ChatVertexAIComponent
@ -16,11 +14,9 @@ __all__ = [
"AnthropicLLM", "AnthropicLLM",
"AzureChatOpenAIComponent", "AzureChatOpenAIComponent",
"QianfanChatEndpointComponent", "QianfanChatEndpointComponent",
"CTransformersComponent",
"CohereComponent", "CohereComponent",
"GoogleGenerativeAIComponent", "GoogleGenerativeAIComponent",
"HuggingFaceEndpointsComponent", "HuggingFaceEndpointsComponent",
"LlamaCppComponent",
"ChatOllamaComponent", "ChatOllamaComponent",
"OpenAIModelComponent", "OpenAIModelComponent",
"ChatVertexAIComponent", "ChatVertexAIComponent",

View file

@ -7,7 +7,7 @@ from langflow.schema import Record
class ChatOutput(ChatComponent): class ChatOutput(ChatComponent):
display_name = "Chat Output" display_name = "Chat Output"
description = "Used to send a message to the chat." description = "Used to send a chat message."
icon = "ChatOutput" icon = "ChatOutput"
def build( def build(
@ -17,6 +17,7 @@ class ChatOutput(ChatComponent):
input_value: Optional[str] = None, input_value: Optional[str] = None,
session_id: Optional[str] = None, session_id: Optional[str] = None,
return_record: Optional[bool] = False, return_record: Optional[bool] = False,
record_template: Optional[str] = "{text}",
) -> Union[Text, Record]: ) -> Union[Text, Record]:
return super().build( return super().build(
sender=sender, sender=sender,
@ -24,4 +25,5 @@ class ChatOutput(ChatComponent):
input_value=input_value, input_value=input_value,
session_id=session_id, session_id=session_id,
return_record=return_record, return_record=return_record,
record_template=record_template,
) )

View file

@ -6,11 +6,17 @@ from langflow.field_typing import Text
class TextOutput(TextComponent): class TextOutput(TextComponent):
display_name = "Text Output" display_name = "Text Output"
description = "Used to pass text output to the next component." description = "Used to send a text output."
field_config = { def build_config(self):
"input_value": {"display_name": "Value"}, return {
} "input_value": {
"display_name": "Value",
"input_types": ["Record"],
"info": "Text or Record to be passed as output.",
},
"record_template": {"display_name": "Record Template", "multiline": True},
}
def build(self, input_value: Optional[Text] = "") -> Text: def build(self, input_value: Optional[Text] = "", record_template: str = "{text}") -> Text:
return super().build(input_value=input_value) return super().build(input_value=input_value, record_template=record_template)

View file

@ -2,10 +2,12 @@ from .AmazonKendra import AmazonKendraRetrieverComponent
from .MetalRetriever import MetalRetrieverComponent from .MetalRetriever import MetalRetrieverComponent
from .MultiQueryRetriever import MultiQueryRetrieverComponent from .MultiQueryRetriever import MultiQueryRetrieverComponent
from .VectaraSelfQueryRetriver import VectaraSelfQueryRetriverComponent from .VectaraSelfQueryRetriver import VectaraSelfQueryRetriverComponent
from .VectorStoreRetriever import VectoStoreRetrieverComponent
__all__ = [ __all__ = [
"AmazonKendraRetrieverComponent", "AmazonKendraRetrieverComponent",
"MetalRetrieverComponent", "MetalRetrieverComponent",
"MultiQueryRetrieverComponent", "MultiQueryRetrieverComponent",
"VectaraSelfQueryRetriverComponent", "VectaraSelfQueryRetriverComponent",
"VectoStoreRetrieverComponent",
] ]

View file

@ -0,0 +1,5 @@
from .RetrieverTool import RetrieverToolComponent
from .SearchAPITool import SearchApiToolComponent
from .SearchApi import SearchApi
__all__ = ["RetrieverToolComponent", "SearchApiToolComponent", "SearchApi"]

View file

@ -23,51 +23,73 @@ class AstraDBSearchComponent(LCVectorStoreComponent):
"info": "Input value to search", "info": "Input value to search",
}, },
"embedding": {"display_name": "Embedding", "info": "Embedding to use"}, "embedding": {"display_name": "Embedding", "info": "Embedding to use"},
"collection_name": {"display_name": "Collection Name", "info": "Collection name"}, "collection_name": {
"token": {"display_name": "Token", "info": "Token to use", "password": True}, "display_name": "Collection Name",
"api_endpoint": {"display_name": "API Endpoint", "info": "API Endpoint to use"}, "info": "The name of the collection within AstraDB where the vectors will be stored.",
"namespace": {"display_name": "Namespace", "info": "Namespace to use", "advanced": True}, },
"metric": {"display_name": "Metric", "info": "Metric to use", "advanced": True}, "token": {
"batch_size": {"display_name": "Batch Size", "info": "Batch size to use", "advanced": True}, "display_name": "Token",
"info": "Authentication token for accessing AstraDB.",
"password": True,
},
"api_endpoint": {
"display_name": "API Endpoint",
"info": "API endpoint URL for the AstraDB service.",
},
"namespace": {
"display_name": "Namespace",
"info": "Optional namespace within AstraDB to use for the collection.",
"advanced": True,
},
"metric": {
"display_name": "Metric",
"info": "Optional distance metric for vector comparisons in the vector store.",
"advanced": True,
},
"batch_size": {
"display_name": "Batch Size",
"info": "Optional number of records to process in a single batch.",
"advanced": True,
},
"bulk_insert_batch_concurrency": { "bulk_insert_batch_concurrency": {
"display_name": "Bulk Insert Batch Concurrency", "display_name": "Bulk Insert Batch Concurrency",
"info": "Bulk Insert Batch Concurrency to use", "info": "Optional concurrency level for bulk insert operations.",
"advanced": True, "advanced": True,
}, },
"bulk_insert_overwrite_concurrency": { "bulk_insert_overwrite_concurrency": {
"display_name": "Bulk Insert Overwrite Concurrency", "display_name": "Bulk Insert Overwrite Concurrency",
"info": "Bulk Insert Overwrite Concurrency to use", "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
"advanced": True, "advanced": True,
}, },
"bulk_delete_concurrency": { "bulk_delete_concurrency": {
"display_name": "Bulk Delete Concurrency", "display_name": "Bulk Delete Concurrency",
"info": "Bulk Delete Concurrency to use", "info": "Optional concurrency level for bulk delete operations.",
"advanced": True, "advanced": True,
}, },
"setup_mode": { "setup_mode": {
"display_name": "Setup Mode", "display_name": "Setup Mode",
"info": "Setup mode for the vector store", "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.",
"options": ["Sync", "Async", "Off"], "options": ["Sync", "Async", "Off"],
"advanced": True, "advanced": True,
}, },
"pre_delete_collection": { "pre_delete_collection": {
"display_name": "Pre Delete Collection", "display_name": "Pre Delete Collection",
"info": "Pre delete collection", "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
"advanced": True, "advanced": True,
}, },
"metadata_indexing_include": { "metadata_indexing_include": {
"display_name": "Metadata Indexing Include", "display_name": "Metadata Indexing Include",
"info": "Metadata Indexing Include", "info": "Optional list of metadata fields to include in the indexing.",
"advanced": True, "advanced": True,
}, },
"metadata_indexing_exclude": { "metadata_indexing_exclude": {
"display_name": "Metadata Indexing Exclude", "display_name": "Metadata Indexing Exclude",
"info": "Metadata Indexing Exclude", "info": "Optional list of metadata fields to exclude from the indexing.",
"advanced": True, "advanced": True,
}, },
"collection_indexing_policy": { "collection_indexing_policy": {
"display_name": "Collection Indexing Policy", "display_name": "Collection Indexing Policy",
"info": "Collection Indexing Policy", "info": "Optional dictionary defining the indexing policy for the collection.",
"advanced": True, "advanced": True,
}, },
} }
@ -77,9 +99,9 @@ class AstraDBSearchComponent(LCVectorStoreComponent):
embedding: Embeddings, embedding: Embeddings,
collection_name: str, collection_name: str,
input_value: Text, input_value: Text,
token: str,
api_endpoint: str,
search_type: str = "Similarity", search_type: str = "Similarity",
token: Optional[str] = None,
api_endpoint: Optional[str] = None,
namespace: Optional[str] = None, namespace: Optional[str] = None,
metric: Optional[str] = None, metric: Optional[str] = None,
batch_size: Optional[int] = None, batch_size: Optional[int] = None,

View file

@ -0,0 +1,25 @@
from .AstraDBSearch import AstraDBSearchComponent
from .ChromaSearch import ChromaSearchComponent
from .FAISSSearch import FAISSSearchComponent
from .MongoDBAtlasVectorSearch import MongoDBAtlasSearchComponent
from .PineconeSearch import PineconeSearchComponent
from .QdrantSearch import QdrantSearchComponent
from .RedisSearch import RedisSearchComponent
from .SupabaseVectorStoreSearch import SupabaseSearchComponent
from .VectaraSearch import VectaraSearchComponent
from .WeaviateSearch import WeaviateSearchVectorStore
from .pgvectorSearch import PGVectorSearchComponent
__all__ = [
"AstraDBSearchComponent",
"ChromaSearchComponent",
"FAISSSearchComponent",
"MongoDBAtlasSearchComponent",
"PineconeSearchComponent",
"QdrantSearchComponent",
"RedisSearchComponent",
"SupabaseSearchComponent",
"VectaraSearchComponent",
"WeaviateSearchVectorStore",
"PGVectorSearchComponent",
]

View file

@ -16,53 +16,78 @@ class AstraDBVectorStoreComponent(CustomComponent):
def build_config(self): def build_config(self):
return { return {
"inputs": {"display_name": "Inputs", "info": "Inputs to AstraDB"}, "inputs": {
"display_name": "Inputs",
"info": "Optional list of records to be processed and stored in the vector store.",
},
"embedding": {"display_name": "Embedding", "info": "Embedding to use"}, "embedding": {"display_name": "Embedding", "info": "Embedding to use"},
"collection_name": {"display_name": "Collection Name", "info": "Collection name"}, "collection_name": {
"token": {"display_name": "Token", "info": "Token to use", "password": True}, "display_name": "Collection Name",
"api_endpoint": {"display_name": "API Endpoint", "info": "API Endpoint to use"}, "info": "The name of the collection within AstraDB where the vectors will be stored.",
"namespace": {"display_name": "Namespace", "info": "Namespace to use", "advanced": True}, },
"metric": {"display_name": "Metric", "info": "Metric to use", "advanced": True}, "token": {
"batch_size": {"display_name": "Batch Size", "info": "Batch size to use", "advanced": True}, "display_name": "Token",
"info": "Authentication token for accessing AstraDB.",
"password": True,
},
"api_endpoint": {
"display_name": "API Endpoint",
"info": "API endpoint URL for the AstraDB service.",
},
"namespace": {
"display_name": "Namespace",
"info": "Optional namespace within AstraDB to use for the collection.",
"advanced": True,
},
"metric": {
"display_name": "Metric",
"info": "Optional distance metric for vector comparisons in the vector store.",
"advanced": True,
},
"batch_size": {
"display_name": "Batch Size",
"info": "Optional number of records to process in a single batch.",
"advanced": True,
},
"bulk_insert_batch_concurrency": { "bulk_insert_batch_concurrency": {
"display_name": "Bulk Insert Batch Concurrency", "display_name": "Bulk Insert Batch Concurrency",
"info": "Bulk Insert Batch Concurrency to use", "info": "Optional concurrency level for bulk insert operations.",
"advanced": True, "advanced": True,
}, },
"bulk_insert_overwrite_concurrency": { "bulk_insert_overwrite_concurrency": {
"display_name": "Bulk Insert Overwrite Concurrency", "display_name": "Bulk Insert Overwrite Concurrency",
"info": "Bulk Insert Overwrite Concurrency to use", "info": "Optional concurrency level for bulk insert operations that overwrite existing records.",
"advanced": True, "advanced": True,
}, },
"bulk_delete_concurrency": { "bulk_delete_concurrency": {
"display_name": "Bulk Delete Concurrency", "display_name": "Bulk Delete Concurrency",
"info": "Bulk Delete Concurrency to use", "info": "Optional concurrency level for bulk delete operations.",
"advanced": True, "advanced": True,
}, },
"setup_mode": { "setup_mode": {
"display_name": "Setup Mode", "display_name": "Setup Mode",
"info": "Setup mode for the vector store", "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.",
"options": ["Sync", "Async", "Off"], "options": ["Sync", "Async", "Off"],
"advanced": True, "advanced": True,
}, },
"pre_delete_collection": { "pre_delete_collection": {
"display_name": "Pre Delete Collection", "display_name": "Pre Delete Collection",
"info": "Pre delete collection", "info": "Boolean flag to determine whether to delete the collection before creating a new one.",
"advanced": True, "advanced": True,
}, },
"metadata_indexing_include": { "metadata_indexing_include": {
"display_name": "Metadata Indexing Include", "display_name": "Metadata Indexing Include",
"info": "Metadata Indexing Include", "info": "Optional list of metadata fields to include in the indexing.",
"advanced": True, "advanced": True,
}, },
"metadata_indexing_exclude": { "metadata_indexing_exclude": {
"display_name": "Metadata Indexing Exclude", "display_name": "Metadata Indexing Exclude",
"info": "Metadata Indexing Exclude", "info": "Optional list of metadata fields to exclude from the indexing.",
"advanced": True, "advanced": True,
}, },
"collection_indexing_policy": { "collection_indexing_policy": {
"display_name": "Collection Indexing Policy", "display_name": "Collection Indexing Policy",
"info": "Collection Indexing Policy", "info": "Optional dictionary defining the indexing policy for the collection.",
"advanced": True, "advanced": True,
}, },
} }
@ -70,17 +95,17 @@ class AstraDBVectorStoreComponent(CustomComponent):
def build( def build(
self, self,
embedding: Embeddings, embedding: Embeddings,
token: str,
api_endpoint: str,
collection_name: str, collection_name: str,
inputs: Optional[List[Record]] = None, inputs: Optional[List[Record]] = None,
token: Optional[str] = None,
api_endpoint: Optional[str] = None,
namespace: Optional[str] = None, namespace: Optional[str] = None,
metric: Optional[str] = None, metric: Optional[str] = None,
batch_size: Optional[int] = None, batch_size: Optional[int] = None,
bulk_insert_batch_concurrency: Optional[int] = None, bulk_insert_batch_concurrency: Optional[int] = None,
bulk_insert_overwrite_concurrency: Optional[int] = None, bulk_insert_overwrite_concurrency: Optional[int] = None,
bulk_delete_concurrency: Optional[int] = None, bulk_delete_concurrency: Optional[int] = None,
setup_mode: str = "Sync", setup_mode: str = "Async",
pre_delete_collection: bool = False, pre_delete_collection: bool = False,
metadata_indexing_include: Optional[List[str]] = None, metadata_indexing_include: Optional[List[str]] = None,
metadata_indexing_exclude: Optional[List[str]] = None, metadata_indexing_exclude: Optional[List[str]] = None,

View file

@ -1,44 +1,26 @@
from .AstraDB import AstraDBVectorStoreComponent
from .Chroma import ChromaComponent from .Chroma import ChromaComponent
from .ChromaSearch import ChromaSearchComponent
from .FAISS import FAISSComponent from .FAISS import FAISSComponent
from .FAISSSearch import FAISSSearchComponent
from .MongoDBAtlasVector import MongoDBAtlasComponent from .MongoDBAtlasVector import MongoDBAtlasComponent
from .MongoDBAtlasVectorSearch import MongoDBAtlasSearchComponent
from .Pinecone import PineconeComponent from .Pinecone import PineconeComponent
from .PineconeSearch import PineconeSearchComponent
from .Qdrant import QdrantComponent from .Qdrant import QdrantComponent
from .QdrantSearch import QdrantSearchComponent
from .Redis import RedisComponent from .Redis import RedisComponent
from .RedisSearch import RedisSearchComponent
from .SupabaseVectorStore import SupabaseComponent from .SupabaseVectorStore import SupabaseComponent
from .SupabaseVectorStoreSearch import SupabaseSearchComponent
from .Vectara import VectaraComponent from .Vectara import VectaraComponent
from .VectaraSearch import VectaraSearchComponent
from .Weaviate import WeaviateVectorStoreComponent from .Weaviate import WeaviateVectorStoreComponent
from .WeaviateSearch import WeaviateSearchVectorStore
from .pgvector import PGVectorComponent from .pgvector import PGVectorComponent
from .pgvectorSearch import PGVectorSearchComponent
__all__ = [ __all__ = [
"AstraDBVectorStoreComponent",
"ChromaComponent", "ChromaComponent",
"ChromaSearchComponent",
"FAISSComponent", "FAISSComponent",
"FAISSSearchComponent",
"MongoDBAtlasComponent", "MongoDBAtlasComponent",
"MongoDBAtlasSearchComponent",
"PineconeComponent", "PineconeComponent",
"PineconeSearchComponent",
"QdrantComponent", "QdrantComponent",
"QdrantSearchComponent",
"RedisComponent", "RedisComponent",
"RedisSearchComponent",
"SupabaseComponent", "SupabaseComponent",
"SupabaseSearchComponent",
"VectaraComponent", "VectaraComponent",
"VectaraSearchComponent",
"WeaviateVectorStoreComponent", "WeaviateVectorStoreComponent",
"WeaviateSearchVectorStore",
"base", "base",
"PGVectorComponent", "PGVectorComponent",
"PGVectorSearchComponent",
] ]

View file

@ -237,10 +237,28 @@ class CodeParser:
def parse_return_statement(self, node: ast.FunctionDef) -> bool: def parse_return_statement(self, node: ast.FunctionDef) -> bool:
""" """
Parses the return statement of a function or method node. Parses the return statement of a function or method node, including nested returns.
""" """
return any(isinstance(n, ast.Return) for n in node.body) def has_return(node):
if isinstance(node, ast.Return):
return True
elif isinstance(node, ast.If):
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
elif isinstance(node, ast.Try):
return (
any(has_return(child) for child in node.body)
or any(has_return(child) for child in node.handlers)
or any(has_return(child) for child in node.finalbody)
)
elif isinstance(node, (ast.For, ast.While)):
return any(has_return(child) for child in node.body) or any(has_return(child) for child in node.orelse)
elif isinstance(node, ast.With):
return any(has_return(child) for child in node.body)
else:
return False
return any(has_return(child) for child in node.body)
def parse_assign(self, stmt): def parse_assign(self, stmt):
""" """

View file

@ -32,6 +32,8 @@ def check_tools_in_params(params: Dict):
def instantiate_from_template(class_object, params: Dict): def instantiate_from_template(class_object, params: Dict):
from_template_params = {"template": params.pop("prompt", params.pop("template", ""))} from_template_params = {"template": params.pop("prompt", params.pop("template", ""))}
from_template_params.update(params)
if not from_template_params.get("template"): if not from_template_params.get("template"):
raise ValueError("Prompt template is required") raise ValueError("Prompt template is required")
return class_object.from_template(**from_template_params) return class_object.from_template(**from_template_params)

View file

@ -4,6 +4,7 @@ from loguru import logger
from langflow.interface.base import LangChainTypeCreator from langflow.interface.base import LangChainTypeCreator
from langflow.interface.custom_lists import llm_type_to_cls_dict from langflow.interface.custom_lists import llm_type_to_cls_dict
from langflow.services.deps import get_settings_service
from langflow.template.frontend_node.llms import LLMFrontendNode from langflow.template.frontend_node.llms import LLMFrontendNode
from langflow.utils.util import build_template_from_class from langflow.utils.util import build_template_from_class
@ -33,10 +34,11 @@ class LLMCreator(LangChainTypeCreator):
return None return None
def to_list(self) -> List[str]: def to_list(self) -> List[str]:
settings_service = get_settings_service()
return [ return [
llm.__name__ llm.__name__
for llm in self.type_to_loader_dict.values() for llm in self.type_to_loader_dict.values()
# if llm.__name__ in settings_service.settings.LLMS or settings_service.settings.DEV if llm.__name__ in settings_service.settings.LLMS or settings_service.settings.DEV
] ]

View file

@ -1,7 +1,7 @@
from importlib import metadata from importlib import metadata
try: try:
__version__ = metadata.version(__package__) __version__ = metadata.version("langflow")
except metadata.PackageNotFoundError: except metadata.PackageNotFoundError:
__version__ = "" __version__ = ""
del metadata del metadata

View file

@ -55,7 +55,7 @@
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11", "react-error-boundary": "^4.0.11",
"react-icons": "^4.10.1", "react-icons": "^5.0.1",
"react-laag": "^2.0.5", "react-laag": "^2.0.5",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"react-router-dom": "^6.15.0", "react-router-dom": "^6.15.0",
@ -9363,9 +9363,9 @@
} }
}, },
"node_modules/react-icons": { "node_modules/react-icons": {
"version": "4.12.0", "version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.12.0.tgz", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.0.1.tgz",
"integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==", "integrity": "sha512-WqLZJ4bLzlhmsvme6iFdgO8gfZP17rfjYEJ2m9RsZjZ+cc4k1hTzknEz63YS1MeT50kVzoa1Nz36f4BEx+Wigw==",
"peerDependencies": { "peerDependencies": {
"react": "*" "react": "*"
} }

View file

@ -50,7 +50,7 @@
"react-cookie": "^4.1.1", "react-cookie": "^4.1.1",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11", "react-error-boundary": "^4.0.11",
"react-icons": "^4.10.1", "react-icons": "^5.0.1",
"react-laag": "^2.0.5", "react-laag": "^2.0.5",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
"react-router-dom": "^6.15.0", "react-router-dom": "^6.15.0",

View file

@ -211,10 +211,12 @@ export default function GenericNode({
} }
}, [validationStatus, validationStatus?.params]); }, [validationStatus, validationStatus?.params]);
// const showNode = data.showNode ?? true;
const [showNode, setShowNode] = useState(data.showNode ?? true); const [showNode, setShowNode] = useState(data.showNode ?? true);
useEffect(() => {
setShowNode(data.showNode ?? true);
}, [data.showNode]);
const nameEditable = true; const nameEditable = true;
const emojiRegex = /\p{Emoji}/u; const emojiRegex = /\p{Emoji}/u;
@ -438,7 +440,7 @@ export default function GenericNode({
event.preventDefault(); event.preventDefault();
}} }}
data-testid={"title-" + data.node?.display_name} data-testid={"title-" + data.node?.display_name}
className="generic-node-tooltip-div text-primary" className="generic-node-tooltip-div cursor-text text-primary"
> >
{data.node?.display_name} {data.node?.display_name}
</div> </div>

View file

@ -13,6 +13,8 @@ export default function DropdownButton({
firstButtonName, firstButtonName,
onFirstBtnClick, onFirstBtnClick,
options, options,
plusButton = false,
dropdownOptions = true,
}: dropdownButtonPropsType): JSX.Element { }: dropdownButtonPropsType): JSX.Element {
const [showOptions, setShowOptions] = useState<boolean>(false); const [showOptions, setShowOptions] = useState<boolean>(false);
@ -23,28 +25,33 @@ export default function DropdownButton({
<Button <Button
id="new-project-btn" id="new-project-btn"
variant="primary" variant="primary"
className="relative pr-10" className={"relative" + dropdownOptions ? "" : " pr-10"}
onClick={(event) => { onClick={(event) => {
event.stopPropagation(); event.stopPropagation();
event.preventDefault(); event.preventDefault();
onFirstBtnClick(); onFirstBtnClick();
}} }}
> >
{plusButton && (
<IconComponent name="Plus" className="main-page-nav-button" />
)}
{firstButtonName} {firstButtonName}
<div {dropdownOptions && (
className="absolute right-2 items-center text-muted-foreground" <div
onClick={(event) => { className="absolute right-2 items-center text-muted-foreground"
event.stopPropagation(); onClick={(event) => {
event.preventDefault(); event.stopPropagation();
setShowOptions(!showOptions); event.preventDefault();
}} setShowOptions(!showOptions);
> }}
{!showOptions ? ( >
<IconComponent name="ChevronDown" /> {!showOptions ? (
) : ( <IconComponent name="ChevronDown" />
<IconComponent name="ChevronUp" /> ) : (
)} <IconComponent name="ChevronUp" />
</div> )}
</div>
)}
</Button> </Button>
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent <DropdownMenuContent

View file

@ -120,7 +120,7 @@ export default function IOView({
{/* TODO ADAPT TO ALL TYPES OF INPUTS AND OUTPUTS */} {/* TODO ADAPT TO ALL TYPES OF INPUTS AND OUTPUTS */}
<BaseModal.Header description={CHAT_FORM_DIALOG_SUBTITLE}> <BaseModal.Header description={CHAT_FORM_DIALOG_SUBTITLE}>
<div className="flex items-center"> <div className="flex items-center">
<span className="pr-2">Chat</span> <span className="pr-2">Interaction Panel</span>
<IconComponent <IconComponent
name="prompts" name="prompts"
className="h-6 w-6 pl-1 text-foreground" className="h-6 w-6 pl-1 text-foreground"

View file

@ -1,5 +1,6 @@
import { useContext, useEffect } from "react"; import { useContext, useEffect } from "react";
import { FaDiscord, FaGithub, FaTwitter } from "react-icons/fa"; import { FaDiscord, FaGithub } from "react-icons/fa";
import { RiTwitterXFill } from "react-icons/ri";
import { Link, useLocation, useNavigate, useParams } from "react-router-dom"; import { Link, useLocation, useNavigate, useParams } from "react-router-dom";
import AlertDropdown from "../../alerts/alertDropDown"; import AlertDropdown from "../../alerts/alertDropDown";
import { USER_PROJECTS_HEADER } from "../../constants/constants"; import { USER_PROJECTS_HEADER } from "../../constants/constants";
@ -127,7 +128,7 @@ export default function Header(): JSX.Element {
rel="noreferrer" rel="noreferrer"
className="text-muted-foreground" className="text-muted-foreground"
> >
<FaTwitter className="side-bar-button-size" /> <RiTwitterXFill className="side-bar-button-size" />
</a> </a>
<a <a
href="https://discord.gg/EqksyE2EX9" href="https://discord.gg/EqksyE2EX9"

View file

@ -99,12 +99,16 @@ export default function InputComponent({
type="text" type="text"
onBlur={onInputLostFocus} onBlur={onInputLostFocus}
value={ value={
selectedOption !== "" || !onChange ? selectedOption : value (selectedOption !== "" || !onChange) && setSelectedOption
? selectedOption
: value
} }
autoFocus={autoFocus} autoFocus={autoFocus}
disabled={disabled} disabled={disabled}
onClick={() => { onClick={() => {
(selectedOption !== "" || !onChange) && setShowOptions(true); (selectedOption !== "" || !onChange) &&
setSelectedOption &&
setShowOptions(true);
}} }}
required={required} required={required}
className={classNames( className={classNames(
@ -115,8 +119,12 @@ export default function InputComponent({
? " text-clip password " ? " text-clip password "
: "", : "",
editNode ? " input-edit-node " : "", editNode ? " input-edit-node " : "",
password && selectedOption === "" && editNode ? "pr-8" : "", password && setSelectedOption ? "pr-16" : "",
password && selectedOption === "" && !editNode ? "pr-10" : "", (!password && setSelectedOption) ||
(password && !setSelectedOption)
? "pr-8"
: "",
className! className!
)} )}
placeholder={password && editNode ? "Key" : placeholder} placeholder={password && editNode ? "Key" : placeholder}
@ -179,18 +187,32 @@ export default function InputComponent({
setShowOptions(false); setShowOptions(false);
}} }}
> >
<div className="flex w-full items-center justify-between"> <div className="group flex w-full items-center justify-between">
<div className="flex items-center"> <div className="flex items-center">
<ForwardedIconComponent <div
name="Check"
className={cn( className={cn(
"mr-2 h-4 w-4 text-primary", "relative mr-2 h-4 w-4",
selectedOption === option selectedOption === option
? "opacity-100" ? "opacity-100"
: "opacity-0" : "opacity-0"
)} )}
aria-hidden="true" >
/> <div className="absolute opacity-100 transition-all group-hover:opacity-0">
<ForwardedIconComponent
name="Check"
className="mr-2 h-4 w-4 text-primary"
aria-hidden="true"
/>
</div>
<div className="absolute opacity-0 transition-all group-hover:opacity-100">
<ForwardedIconComponent
name="X"
className="mr-2 h-4 w-4 text-status-red"
aria-hidden="true"
/>
</div>
</div>
{option} {option}
</div> </div>
{optionButton && optionButton(option)} {optionButton && optionButton(option)}
@ -206,10 +228,12 @@ export default function InputComponent({
<div <div
className={cn( className={cn(
"pointer-events-auto absolute inset-y-0 h-full w-full cursor-pointer", "pointer-events-auto absolute inset-y-0 h-full w-full cursor-pointer",
selectedOption !== "" || !onChange ? "" : "hidden" (selectedOption !== "" || !onChange) && setSelectedOption
? ""
: "hidden"
)} )}
onClick={ onClick={
selectedOption !== "" || !onChange (selectedOption !== "" || !onChange) && setSelectedOption
? (e) => { ? (e) => {
setShowOptions((old) => !old); setShowOptions((old) => !old);
e.preventDefault(); e.preventDefault();
@ -221,30 +245,32 @@ export default function InputComponent({
</> </>
)} )}
<span {setSelectedOption && (
className={cn( <span
password && selectedOption === "" ? "right-8" : "right-0",
"absolute inset-y-0 flex items-center pr-2.5"
)}
>
<button
onClick={() => {
setShowOptions(!showOptions);
}}
className={cn( className={cn(
selectedOption !== "" password && selectedOption === "" ? "right-8" : "right-0",
? "text-medium-indigo" "absolute inset-y-0 flex items-center pr-2.5"
: "text-muted-foreground",
"hover:text-accent-foreground"
)} )}
> >
<ForwardedIconComponent <button
name={optionsIcon} onClick={() => {
className={"h-4 w-4"} setShowOptions(!showOptions);
aria-hidden="true" }}
/> className={cn(
</button> selectedOption !== ""
</span> ? "text-medium-indigo"
: "text-muted-foreground",
"hover:text-accent-foreground"
)}
>
<ForwardedIconComponent
name={optionsIcon}
className={"h-4 w-4"}
aria-hidden="true"
/>
</button>
</span>
)}
{password && selectedOption === "" && ( {password && selectedOption === "" && (
<button <button

View file

@ -107,7 +107,7 @@ export const CODE_DIALOG_SUBTITLE =
* @constant * @constant
*/ */
export const CHAT_FORM_DIALOG_SUBTITLE = export const CHAT_FORM_DIALOG_SUBTITLE =
"Set up the input variables defined in prompt templates. Interact with agents and chains."; "Adjust or overwrite input values, inspect outputs or interact through the chat console.";
/** /**
* The base text for subtitle of Edit Node Dialog * The base text for subtitle of Edit Node Dialog
@ -732,12 +732,12 @@ export const PRIORITY_SIDEBAR_ORDER = [
"saved_components", "saved_components",
"inputs", "inputs",
"outputs", "outputs",
"prompts",
"data", "data",
"prompt", "prompt",
"models", "models",
"vectorstores",
"vectorsearch",
"helpers", "helpers",
"experimental",
]; ];
export const NATIVE_CATEGORIES = [ export const NATIVE_CATEGORIES = [
"inputs", "inputs",

View file

@ -33,7 +33,7 @@ export default function ChatInput({
<div className="relative"> <div className="relative">
<Textarea <Textarea
onKeyDown={(event) => { onKeyDown={(event) => {
if (event.key === "Enter" && !lockChat && !event.shiftKey) { if (event.key === "Enter" && !event.nativeEvent.isComposing && !lockChat && !event.shiftKey) {
sendMessage(); sendMessage();
} }
}} }}

View file

@ -5,7 +5,6 @@ import ShadTooltip from "../../../../components/ShadTooltipComponent";
import IconComponent from "../../../../components/genericIconComponent"; import IconComponent from "../../../../components/genericIconComponent";
import { Input } from "../../../../components/ui/input"; import { Input } from "../../../../components/ui/input";
import { Separator } from "../../../../components/ui/separator"; import { Separator } from "../../../../components/ui/separator";
import { PRIORITY_SIDEBAR_ORDER } from "../../../../constants/constants";
import ExportModal from "../../../../modals/exportModal"; import ExportModal from "../../../../modals/exportModal";
import ShareModal from "../../../../modals/shareModal"; import ShareModal from "../../../../modals/shareModal";
import useAlertStore from "../../../../stores/alertStore"; import useAlertStore from "../../../../stores/alertStore";
@ -282,35 +281,7 @@ export default function ExtraSidebar(): JSX.Element {
</div> </div>
</div> </div>
)} )}
{index === PRIORITY_SIDEBAR_ORDER.length - 1 && (
<>
<a
target={"_blank"}
href="https://langflow.store"
className="components-disclosure-arrangement"
>
<div className="flex gap-4">
{/* BUG ON THIS ICON */}
<SparklesIcon
strokeWidth={1.5}
className="w-[22px] text-primary"
/>
<span className="components-disclosure-title">
Discover More
</span>
</div>
<div className="components-disclosure-div">
<div>
<LinkIcon className="h-4 w-4 text-foreground" />
</div>
</div>
</a>
<div className="p-2 px-4 text-sm font-semibold" key={index}>
Legacy Components
</div>
</>
)}
<DisclosureComponent <DisclosureComponent
openDisc={ openDisc={
getFilterEdge.length !== 0 || search.length !== 0 getFilterEdge.length !== 0 || search.length !== 0
@ -371,6 +342,32 @@ export default function ExtraSidebar(): JSX.Element {
))} ))}
</div> </div>
</DisclosureComponent> </DisclosureComponent>
{index === Object.keys(dataFilter).length - 1 && (
<>
<a
target={"_blank"}
href="https://langflow.store"
className="components-disclosure-arrangement"
>
<div className="flex gap-4">
{/* BUG ON THIS ICON */}
<SparklesIcon
strokeWidth={1.5}
className="w-[22px] text-primary"
/>
<span className="components-disclosure-title">
Discover More
</span>
</div>
<div className="components-disclosure-div">
<div>
<LinkIcon className="h-4 w-4 text-foreground" />
</div>
</div>
</a>
</>
)}
</> </>
) : ( ) : (
<div key={index}></div> <div key={index}></div>

View file

@ -85,7 +85,9 @@ export default function NodeToolbarComponent({
const [showModalAdvanced, setShowModalAdvanced] = useState(false); const [showModalAdvanced, setShowModalAdvanced] = useState(false);
const [showconfirmShare, setShowconfirmShare] = useState(false); const [showconfirmShare, setShowconfirmShare] = useState(false);
const [showOverrideModal, setShowOverrideModal] = useState(false); const [showOverrideModal, setShowOverrideModal] = useState(false);
const [flowComponent, setFlowComponent] = useState<FlowType>(); const [flowComponent, setFlowComponent] = useState<FlowType>(
createFlowComponent(cloneDeep(data), version)
);
const openInNewTab = (url) => { const openInNewTab = (url) => {
window.open(url, "_blank", "noreferrer"); window.open(url, "_blank", "noreferrer");
@ -285,7 +287,13 @@ export default function NodeToolbarComponent({
event.preventDefault(); event.preventDefault();
setShowconfirmShare((state) => !state); setShowconfirmShare((state) => !state);
} }
if (selected && (event.ctrlKey || event.metaKey) && event.key === "q") {
if (
selected &&
(event.ctrlKey || event.metaKey) &&
event.shiftKey &&
event.key === "Q"
) {
event.preventDefault(); event.preventDefault();
if (isMinimal) { if (isMinimal) {
setShowState((show) => !show); setShowState((show) => !show);
@ -341,6 +349,10 @@ export default function NodeToolbarComponent({
title: `${data.id} docs is not available at the moment.`, title: `${data.id} docs is not available at the moment.`,
}); });
} }
if (selected && (event.ctrlKey || event.metaKey) && event.key === "j") {
event.preventDefault();
downloadNode(flowComponent!);
}
} }
document.addEventListener("keydown", onKeyDown); document.addEventListener("keydown", onKeyDown);
@ -499,15 +511,17 @@ export default function NodeToolbarComponent({
/> />
</SelectItem> </SelectItem>
)} )}
{!hasStore && ( {(!hasStore || !hasApiKey || !validApiKey) && (
<SelectItem value={"Download"}> <SelectItem value={"Download"}>
<div className="flex"> <ToolbarSelectItem
<IconComponent value="Download"
name="Download" shift={false}
className="relative top-0.5 mr-2 h-4 w-4" isMac={navigator.userAgent.toUpperCase().includes("MAC")}
/>{" "} icon="Download"
Download{" "} styleObj={{ iconClasses: "relative top-0.5 mr-2 h-4 w-4" }}
</div>{" "} keyboardKey={"J"}
dataTestId={"Dowload-button-nodeToolbar"}
/>
</SelectItem> </SelectItem>
)} )}
<SelectItem <SelectItem
@ -525,24 +539,14 @@ export default function NodeToolbarComponent({
</SelectItem> </SelectItem>
{isMinimal && ( {isMinimal && (
<SelectItem value={"show"}> <SelectItem value={"show"}>
<div className="flex"> <ToolbarSelectItem
<IconComponent icon={showNode ? "Minimize2" : "Maximize2"}
name={showNode ? "Minimize2" : "Maximize2"} value={showNode ? "Minimize" : "Expand"}
className="relative top-0.5 mr-2 h-4 w-4" isMac={navigator.userAgent.toUpperCase().includes("MAC")}
/> shift={true}
{showNode ? "Minimize" : "Expand"} keyboardKey={"Q"}
{navigator.userAgent.toUpperCase().includes("MAC") ? ( dataTestId={"minimize-button-nodeToolbar"}
<IconComponent />
name="Command"
className="absolute right-[1.25rem] top-[0.65em] h-3.5 w-3.5 stroke-2"
></IconComponent>
) : (
<span className="absolute right-[1.30rem] top-[0.40em] stroke-2">
Ctrl +{" "}
</span>
)}
<span className="absolute right-2 top-[0.46em]">Q</span>
</div>
</SelectItem> </SelectItem>
)} )}
{isGroup && ( {isGroup && (

View file

@ -105,6 +105,8 @@ export default function HomePage(): JSX.Element {
firstButtonName="New Project" firstButtonName="New Project"
onFirstBtnClick={() => setOpenModal(true)} onFirstBtnClick={() => setOpenModal(true)}
options={dropdownOptions} options={dropdownOptions}
plusButton={true}
dropdownOptions={false}
/> />
</div> </div>
} }

View file

@ -4,7 +4,7 @@ import { DarkStoreType } from "../types/zustand/dark";
const startedStars = Number(window.localStorage.getItem("githubStars")) ?? 0; const startedStars = Number(window.localStorage.getItem("githubStars")) ?? 0;
export const useDarkStore = create<DarkStoreType>((set) => ({ export const useDarkStore = create<DarkStoreType>((set, get) => ({
dark: JSON.parse(window.localStorage.getItem("isDark")!) ?? false, dark: JSON.parse(window.localStorage.getItem("isDark")!) ?? false,
stars: startedStars, stars: startedStars,
version: "", version: "",
@ -15,14 +15,23 @@ export const useDarkStore = create<DarkStoreType>((set) => ({
}); });
}, },
refreshStars: () => { refreshStars: () => {
if (window.localStorage.getItem("githubStars") !== null) { let lastUpdated = window.localStorage.getItem("githubStarsLastUpdated");
set(() => ({ stars: startedStars })); let diff = 0;
return; // check if lastUpdated actually exists
if (lastUpdated !== null) {
diff = Math.abs(new Date().getTime() - new Date(lastUpdated).getTime());
} }
getRepoStars("logspace-ai", "langflow").then((res) => { // if lastUpdated is null or the difference is greater than 2 hours
window.localStorage.setItem("githubStars", res.toString()); if (lastUpdated === null || diff > 7200000) {
set(() => ({ stars: res })); getRepoStars("logspace-ai", "langflow").then((res) => {
}); window.localStorage.setItem("githubStars", res.toString());
window.localStorage.setItem(
"githubStarsLastUpdated",
new Date().toString()
);
set(() => ({ stars: res, lastUpdated: new Date() }));
});
}
}, },
})); }));

View file

@ -689,6 +689,8 @@ export type dropdownButtonPropsType = {
firstButtonName: string; firstButtonName: string;
onFirstBtnClick: () => void; onFirstBtnClick: () => void;
options: Array<{ name: string; onBtnClick: () => void }>; options: Array<{ name: string; onBtnClick: () => void }>;
plusButton?: boolean;
dropdownOptions?: boolean;
}; };
export type IOInputProps = { export type IOInputProps = {

View file

@ -119,6 +119,8 @@ export async function buildVertices({
try { try {
onValidateNodes(verticesOrderResponse.verticesToRun); onValidateNodes(verticesOrderResponse.verticesToRun);
} catch (e) { } catch (e) {
useFlowStore.getState().setIsBuilding(false);
return; return;
} }
} }

View file

@ -1170,7 +1170,7 @@ export function downloadNode(NodeFLow: FlowType) {
type: "application/json", type: "application/json",
}); });
element.href = URL.createObjectURL(file); element.href = URL.createObjectURL(file);
element.download = `${NodeFLow.name}.json`; element.download = `${NodeFLow?.name??"node"}.json`;
element.click(); element.click();
} }

View file

@ -236,6 +236,7 @@ export const nodeColors: { [char: string]: string } = {
embeddings: "#42BAA7", embeddings: "#42BAA7",
documentloaders: "#7AAE42", documentloaders: "#7AAE42",
vectorstores: "#AA8742", vectorstores: "#AA8742",
vectorsearch: "#AA8742",
textsplitters: "#B47CB5", textsplitters: "#B47CB5",
toolkits: "#DB2C2C", toolkits: "#DB2C2C",
wrappers: "#E6277A", wrappers: "#E6277A",
@ -248,6 +249,7 @@ export const nodeColors: { [char: string]: string } = {
retrievers: "#e6b25a", retrievers: "#e6b25a",
unknown: "#9CA3AF", unknown: "#9CA3AF",
custom_components: "#ab11ab", custom_components: "#ab11ab",
Record:"#31a3cc"
}; };
export const nodeNames: { [char: string]: string } = { export const nodeNames: { [char: string]: string } = {
@ -267,6 +269,7 @@ export const nodeNames: { [char: string]: string } = {
embeddings: "Embeddings", embeddings: "Embeddings",
documentloaders: "Loaders", documentloaders: "Loaders",
vectorstores: "Vector Stores", vectorstores: "Vector Stores",
vectorsearch: "Vector Search",
toolkits: "Toolkits", toolkits: "Toolkits",
wrappers: "Wrappers", wrappers: "Wrappers",
textsplitters: "Text Splitters", textsplitters: "Text Splitters",
@ -369,6 +372,7 @@ export const nodeIconsLucide: iconsType = {
saved_components: GradientSave, saved_components: GradientSave,
documentloaders: Paperclip, documentloaders: Paperclip,
vectorstores: Layers, vectorstores: Layers,
vectorsearch: Search,
toolkits: Package2, toolkits: Package2,
textsplitters: Scissors, textsplitters: Scissors,
wrappers: Gift, wrappers: Gift,
@ -387,7 +391,6 @@ export const nodeIconsLucide: iconsType = {
Trash2, Trash2,
Boxes, Boxes,
Network, Network,
X,
XCircle, XCircle,
Info, Info,
CheckCircle2, CheckCircle2,

View file

@ -0,0 +1,358 @@
{
"id": "3f5e860d-1676-4fba-9d86-06db9f51e43a",
"data": {
"nodes": [
{
"id": "ChatInput-7hPDT",
"type": "genericNode",
"position": {
"x": 687,
"y": 41.9375
},
"data": {
"type": "ChatInput",
"node": {
"template": {
"code": {
"type": "code",
"required": true,
"placeholder": "",
"list": false,
"show": true,
"multiline": true,
"value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Used to get user input from the chat.\"\n icon = \"ChatInput\"\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n",
"fileTypes": [],
"file_path": "",
"password": false,
"name": "code",
"advanced": true,
"dynamic": true,
"info": "",
"load_from_db": false,
"title_case": false
},
"input_value": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": true,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "input_value",
"display_name": "Message",
"advanced": false,
"input_types": ["Text"],
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false
},
"return_record": {
"type": "bool",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"value": false,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "return_record",
"display_name": "Return Record",
"advanced": false,
"dynamic": false,
"info": "Return the message as a record containing the sender, sender_name, and session_id.",
"load_from_db": false,
"title_case": false
},
"sender": {
"type": "str",
"required": false,
"placeholder": "",
"list": true,
"show": true,
"multiline": false,
"value": "User",
"fileTypes": [],
"file_path": "",
"password": false,
"options": ["Machine", "User"],
"name": "sender",
"display_name": "Sender Type",
"advanced": false,
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"sender_name": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"value": "User",
"fileTypes": [],
"file_path": "",
"password": false,
"name": "sender_name",
"display_name": "Sender Name",
"advanced": false,
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"session_id": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "session_id",
"display_name": "Session ID",
"advanced": true,
"dynamic": false,
"info": "If provided, the message will be stored in the memory.",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"_type": "CustomComponent"
},
"description": "Used to get user input from the chat.",
"icon": "ChatInput",
"base_classes": ["Text", "object", "str", "Record"],
"display_name": "Chat Input",
"documentation": "",
"custom_fields": {
"sender": null,
"sender_name": null,
"input_value": null,
"session_id": null,
"return_record": null
},
"output_types": ["Text", "Record"],
"field_formatters": {},
"frozen": false,
"field_order": [],
"beta": false
},
"id": "ChatInput-7hPDT"
},
"selected": false,
"width": 384,
"height": 569,
"positionAbsolute": {
"x": 687,
"y": 41.9375
},
"dragging": false
},
{
"id": "ChatOutput-4sm9Z",
"type": "genericNode",
"position": {
"x": 4.939451516507972,
"y": 103.3695231904992
},
"data": {
"type": "ChatOutput",
"node": {
"template": {
"code": {
"type": "code",
"required": true,
"placeholder": "",
"list": false,
"show": true,
"multiline": true,
"value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema import Record\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Used to send a message to the chat.\"\n icon = \"ChatOutput\"\n\n def build(\n self,\n sender: Optional[str] = \"Machine\",\n sender_name: Optional[str] = \"AI\",\n input_value: Optional[str] = None,\n session_id: Optional[str] = None,\n return_record: Optional[bool] = False,\n ) -> Union[Text, Record]:\n return super().build(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n return_record=return_record,\n )\n",
"fileTypes": [],
"file_path": "",
"password": false,
"name": "code",
"advanced": true,
"dynamic": true,
"info": "",
"load_from_db": false,
"title_case": false
},
"input_value": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": true,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "input_value",
"display_name": "Message",
"advanced": false,
"input_types": ["Text"],
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false
},
"return_record": {
"type": "bool",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"value": false,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "return_record",
"display_name": "Return Record",
"advanced": false,
"dynamic": false,
"info": "Return the message as a record containing the sender, sender_name, and session_id.",
"load_from_db": false,
"title_case": false
},
"sender": {
"type": "str",
"required": false,
"placeholder": "",
"list": true,
"show": true,
"multiline": false,
"value": "Machine",
"fileTypes": [],
"file_path": "",
"password": false,
"options": ["Machine", "User"],
"name": "sender",
"display_name": "Sender Type",
"advanced": false,
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"sender_name": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"value": "AI",
"fileTypes": [],
"file_path": "",
"password": false,
"name": "sender_name",
"display_name": "Sender Name",
"advanced": false,
"dynamic": false,
"info": "",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"session_id": {
"type": "str",
"required": false,
"placeholder": "",
"list": false,
"show": true,
"multiline": false,
"fileTypes": [],
"file_path": "",
"password": false,
"name": "session_id",
"display_name": "Session ID",
"advanced": true,
"dynamic": false,
"info": "If provided, the message will be stored in the memory.",
"load_from_db": false,
"title_case": false,
"input_types": ["Text"]
},
"_type": "CustomComponent"
},
"description": "Used to send a message to the chat.",
"icon": "ChatOutput",
"base_classes": ["Text", "object", "str", "Record"],
"display_name": "Chat Output",
"documentation": "",
"custom_fields": {
"sender": null,
"sender_name": null,
"input_value": null,
"session_id": null,
"return_record": null
},
"output_types": ["Text", "Record"],
"field_formatters": {},
"frozen": false,
"field_order": [],
"beta": false
},
"id": "ChatOutput-4sm9Z"
},
"selected": true,
"width": 384,
"height": 569,
"positionAbsolute": {
"x": 4.939451516507972,
"y": 103.3695231904992
},
"dragging": false
}
],
"edges": [
{
"source": "ChatOutput-4sm9Z",
"sourceHandle": "{œbaseClassesœ:[œTextœ,œobjectœ,œstrœ,œRecordœ],œdataTypeœ:œChatOutputœ,œidœ:œChatOutput-4sm9Zœ}",
"target": "ChatInput-7hPDT",
"targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatInput-7hPDTœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}",
"data": {
"targetHandle": {
"fieldName": "input_value",
"id": "ChatInput-7hPDT",
"inputTypes": ["Text"],
"type": "str"
},
"sourceHandle": {
"baseClasses": ["Text", "object", "str", "Record"],
"dataType": "ChatOutput",
"id": "ChatOutput-4sm9Z"
}
},
"style": {
"stroke": "#555"
},
"className": "stroke-gray-900 stroke-connection",
"id": "reactflow__edge-ChatOutput-4sm9Z{œbaseClassesœ:[œTextœ,œobjectœ,œstrœ,œRecordœ],œdataTypeœ:œChatOutputœ,œidœ:œChatOutput-4sm9Zœ}-ChatInput-7hPDT{œfieldNameœ:œinput_valueœ,œidœ:œChatInput-7hPDTœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}"
}
],
"viewport": {
"x": 316.78239920440234,
"y": 182.84104875768622,
"zoom": 0.6070974421975234
}
},
"description": "flow to test ChatInput and output",
"name": "ChatITest",
"last_tested_version": "1.0.0a0",
"is_component": false
}

View file

@ -0,0 +1,46 @@
import { test } from "@playwright/test";
import { readFileSync } from "fs";
test.beforeEach(async ({ page }) => {
// await page.waitForTimeout(20000);
// test.setTimeout(120000);
});
test("chat_io_teste", async ({ page }) => {
await page.goto("/");
await page.locator("span").filter({ hasText: "My Collection" }).isVisible();
// Read your file into a buffer.
const jsonContent = readFileSync(
"tests/end-to-end/assets/ChatTest.json",
"utf-8"
);
// Create the DataTransfer and File
const dataTransfer = await page.evaluateHandle((data) => {
const dt = new DataTransfer();
// Convert the buffer to a hex array
const file = new File([data], "ChatTest.json", {
type: "application/json",
});
dt.items.add(file);
return dt;
}, jsonContent);
await page.locator('//*[@id="new-project-btn"]').click();
await page.waitForTimeout(2000);
await page.getByTestId("blank-flow").click();
await page.waitForTimeout(2000);
// Now dispatch
await page.dispatchEvent(
'//*[@id="react-flow-id"]/div[1]/div[1]/div',
"drop",
{
dataTransfer,
}
);
await page.getByLabel("fit view").click();
await page.getByText("Run", { exact: true }).click();
await page.getByPlaceholder("Send a message...").click();
await page.getByPlaceholder("Send a message...").fill("teste");
await page.getByRole("button").nth(1).click();
});

View file

@ -25,86 +25,31 @@ test("CodeAreaModalComponent", async ({ page }) => {
await page.getByTestId("code-button-modal").click(); await page.getByTestId("code-button-modal").click();
let value = await page.locator('//*[@id="codeValue"]').inputValue(); let value = await page.locator('//*[@id="codeValue"]').inputValue();
const code =
if ( 'def python_function(text: str) -> str:\n """This is a default python function that returns the input text"""\n return text';
value != const wCode =
'def python_function(text: str) -> str: """This is a default python function that returns the input text""" return text' 'def python_function(text: str) -> st: """This is a default python function that returns the input text""" return text';
) { const assertCode =
expect(false).toBeTruthy(); 'def python_function(text: str) -> str: """This is a default python function that returns the input text""" return text';
} await page
.locator("#CodeEditor div")
.filter({ hasText: "def python_function(text: str" })
.nth(1)
.click();
await page.locator("textarea").press("Control+a");
await page.locator("textarea").fill(wCode);
await page.locator('//*[@id="checkAndSaveBtn"]').click(); await page.locator('//*[@id="checkAndSaveBtn"]').click();
await page.waitForTimeout(1000);
await page.getByTestId("div-generic-node").click();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click();
await page.locator('//*[@id="showdescription"]').click();
expect( expect(
await page.locator('//*[@id="showdescription"]').isChecked() await page.getByText("invalid syntax (<unknown>, line 1)").isVisible()
).toBeFalsy();
await page.locator('//*[@id="showname"]').click();
expect(await page.locator('//*[@id="showname"]').isChecked()).toBeFalsy();
await page.locator('//*[@id="showreturn_direct"]').click();
expect(
await page.locator('//*[@id="showreturn_direct"]').isChecked()
).toBeFalsy();
await page.locator('//*[@id="showdescription"]').click();
expect(
await page.locator('//*[@id="showdescription"]').isChecked()
).toBeTruthy(); ).toBeTruthy();
await page.locator("textarea").press("Control+a");
await page.locator('//*[@id="showname"]').click(); await page.locator("textarea").fill(wCode);
expect(await page.locator('//*[@id="showname"]').isChecked()).toBeTruthy(); await page.locator("textarea").fill(code);
await page.locator('//*[@id="checkAndSaveBtn"]').click();
await page.locator('//*[@id="showreturn_direct"]').click(); expect(await page.getByText("Code is ready to run").isVisible()).toBeTruthy();
expect( await page.getByTestId("code-button-modal").click();
await page.locator('//*[@id="showreturn_direct"]').isChecked() expect(await page.locator('//*[@id="codeValue"]').inputValue()).toBe(
).toBeTruthy(); assertCode
);
await page.locator('//*[@id="showdescription"]').click();
expect(
await page.locator('//*[@id="showdescription"]').isChecked()
).toBeFalsy();
await page.locator('//*[@id="showname"]').click();
expect(await page.locator('//*[@id="showname"]').isChecked()).toBeFalsy();
await page.locator('//*[@id="showreturn_direct"]').click();
expect(
await page.locator('//*[@id="showreturn_direct"]').isChecked()
).toBeFalsy();
await page.locator('//*[@id="showdescription"]').click();
expect(
await page.locator('//*[@id="showdescription"]').isChecked()
).toBeTruthy();
await page.locator('//*[@id="showname"]').click();
expect(await page.locator('//*[@id="showname"]').isChecked()).toBeTruthy();
await page.locator('//*[@id="showreturn_direct"]').click();
expect(
await page.locator('//*[@id="showreturn_direct"]').isChecked()
).toBeTruthy();
await page.locator('//*[@id="saveChangesBtn"]').click();
const plusButtonLocator = page.locator('//*[@id="code-input-0"]');
const elementCount = await plusButtonLocator.count();
if (elementCount === 0) {
expect(true).toBeTruthy();
await page.getByTestId("more-options-modal").click();
await page.getByTestId("edit-button-modal").click();
await page.locator('//*[@id="saveChangesBtn"]').click();
await page.getByTestId("div-generic-node").click();
await page.getByTestId("code-button-modal").click();
}
}); });

View file

@ -0,0 +1,17 @@
import { expect, test } from "@playwright/test";
test("curl_api_generation", async ({ page, context }) => {
await page.goto("/");
await page.locator('//*[@id="new-project-btn"]').click();
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
await page.getByRole("heading", { name: "Data Ingestion" }).click();
await page.waitForTimeout(2000);
await page.getByText("API", { exact: true }).click();
await page.getByRole("tab", { name: "cURL" }).click();
await page.getByRole("button", { name: "Copy Code" }).click();
const handle = await page.evaluateHandle(() =>
navigator.clipboard.readText()
);
const clipboardContent = await handle.jsonValue();
expect(clipboardContent.length).toBeGreaterThan(0);
});

View file

@ -0,0 +1,17 @@
import { expect, test } from "@playwright/test";
test("python_api_generation", async ({ page, context }) => {
await page.goto("/");
await page.locator('//*[@id="new-project-btn"]').click();
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
await page.getByRole("heading", { name: "Data Ingestion" }).click();
await page.waitForTimeout(2000);
await page.getByText("API", { exact: true }).click();
await page.getByRole("tab", { name: "Python API" }).click();
await page.getByRole("button", { name: "Copy Code" }).click();
const handle = await page.evaluateHandle(() =>
navigator.clipboard.readText()
);
const clipboardContent = await handle.jsonValue();
expect(clipboardContent.length).toBeGreaterThan(0);
});

View file

@ -0,0 +1,38 @@
import { expect, test } from "@playwright/test";
test("curl_api_generation", async ({ page, context }) => {
await page.goto("/");
await page.locator('//*[@id="new-project-btn"]').click();
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
await page.getByRole("heading", { name: "Data Ingestion" }).click();
await page.waitForTimeout(2000);
await page.getByText("API", { exact: true }).click();
await page.getByRole("tab", { name: "cURL" }).click();
await page.getByRole("button", { name: "Copy Code" }).click();
const handle = await page.evaluateHandle(() =>
navigator.clipboard.readText()
);
const clipboardContent = await handle.jsonValue();
const oldValue = clipboardContent;
expect(clipboardContent.length).toBeGreaterThan(0);
await page.getByRole("tab", { name: "Tweaks" }).click();
await page
.getByRole("heading", { name: "URL" })
.locator("div")
.first()
.click();
await page.getByRole("textbox", { name: "Type something..." }).click();
await page
.getByRole("textbox", { name: "Type something..." })
.press("Control+a");
await page.getByRole("textbox", { name: "Type something..." }).fill("teste");
await page.getByRole("tab", { name: "cURL" }).click();
await page.getByRole("button", { name: "Copy Code" }).click();
const handle2 = await page.evaluateHandle(() =>
navigator.clipboard.readText()
);
const clipboardContent2 = await handle2.jsonValue();
const newValue = clipboardContent2;
expect(oldValue).not.toBe(newValue);
expect(clipboardContent2.length).toBeGreaterThan(clipboardContent.length);
});