Merge branch 'main' into dev

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-12-13 18:40:50 -03:00
commit 24bb1b2d83
25 changed files with 185 additions and 201 deletions

View file

@ -15,7 +15,7 @@
// "forwardPorts": [], // "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created. // Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "make setup_devcontainer", "postCreateCommand": "make install_frontend && make install_backend",
"containerEnv": { "containerEnv": {
"POETRY_VIRTUALENVS_IN_PROJECT": "true" "POETRY_VIRTUALENVS_IN_PROJECT": "true"
@ -31,13 +31,11 @@
"sourcery.sourcery", "sourcery.sourcery",
"eamodio.gitlens", "eamodio.gitlens",
"ms-vscode.makefile-tools", "ms-vscode.makefile-tools",
"GitHub.vscode-pull-request-github", "GitHub.vscode-pull-request-github"
"Codium.codium",
"ms-azuretools.vscode-docker"
] ]
} }
} }
// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root" // "remoteUser": "root"
} }

View file

@ -56,14 +56,6 @@ LANGFLOW_REMOVE_API_KEYS=
# LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600) # LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600)
LANGFLOW_CACHE_TYPE= LANGFLOW_CACHE_TYPE=
# Auto login
# If set to true then a superuser will be logged in automatically
# and the login page will be skipped, keeping the
# default experience of Langflow
# Values: true, false
# Example: LANGFLOW_AUTO_LOGIN=true
LANGFLOW_AUTO_LOGIN=
# Superuser username # Superuser username
# Example: LANGFLOW_SUPERUSER=admin # Example: LANGFLOW_SUPERUSER=admin
LANGFLOW_SUPERUSER= LANGFLOW_SUPERUSER=

View file

@ -4,18 +4,10 @@ on:
push: push:
branches: branches:
- dev - dev
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
pull_request: pull_request:
branches: branches:
- dev - dev
- main - main
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
jobs: jobs:
build-and-test: build-and-test:

View file

@ -3,16 +3,7 @@ name: lint
on: on:
push: push:
branches: [main] branches: [main]
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
pull_request: pull_request:
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
env: env:
POETRY_VERSION: "1.7.0" POETRY_VERSION: "1.7.0"

View file

@ -3,17 +3,9 @@ name: test
on: on:
push: push:
branches: [main] branches: [main]
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
pull_request: pull_request:
branches: [dev] branches: [dev]
paths:
- "tests/**"
- "src/backend/**"
- "pyproject.toml"
env: env:
POETRY_VERSION: "1.5.0" POETRY_VERSION: "1.5.0"

4
.gitignore vendored
View file

@ -255,6 +255,4 @@ langflow.db
/tmp/* /tmp/*
src/backend/langflow/frontend/ src/backend/langflow/frontend/
.docker .docker
.idea

View file

@ -22,19 +22,13 @@ tests:
@make install_backend @make install_backend
poetry run pytest tests --instafail poetry run pytest tests --instafail
tests_frontend:
ifeq ($(UI), true)
cd src/frontend && ./run-tests.sh --ui
else
cd src/frontend && ./run-tests.sh
endif
format: format:
poetry run ruff . --fix poetry run ruff . --fix
poetry run ruff format . poetry run ruff format .
cd src/frontend && npm run format cd src/frontend && npm run format
lint: lint:
make install_backend
poetry run mypy src/backend/langflow poetry run mypy src/backend/langflow
poetry run ruff . --fix poetry run ruff . --fix
@ -49,20 +43,19 @@ run_frontend:
cd src/frontend && npm start cd src/frontend && npm start
run_cli: run_cli:
poetry run langflow --path src/frontend/build poetry run langflow run --path src/frontend/build
run_cli_debug: run_cli_debug:
poetry run langflow --path src/frontend/build --log-level debug poetry run langflow run --path src/frontend/build --log-level debug
setup_devcontainer: setup_devcontainer:
make init make init
make build_frontend make build_frontend
@echo 'Run Cli' poetry run langflow --path src/frontend/build
make run_cli
frontend: frontend:
@-make install_frontend || (echo "An error occurred while installing frontend dependencies. Attempting to fix." && make install_frontendc) make install_frontend
@make run_frontend make run_frontend
frontendc: frontendc:
make install_frontendc make install_frontendc

View file

@ -217,40 +217,4 @@ Vertex AI is a cloud computing platform offered by Google Cloud Platform (GCP).
- **top_k:** How the model selects tokens for output, the next token is selected from – defaults to `40`. - **top_k:** How the model selects tokens for output, the next token is selected from – defaults to `40`.
- **top_p:** Tokens are selected from most probable to least until the sum of their – defaults to `0.95`. - **top_p:** Tokens are selected from most probable to least until the sum of their – defaults to `0.95`.
- **tuned_model_name:** The name of a tuned model. If provided, model_name is ignored. - **tuned_model_name:** The name of a tuned model. If provided, model_name is ignored.
- **verbose:** This parameter is used to control the level of detail in the output of the chain. When set to True, it will print out some internal states of the chain while it is being run, which can help debug and understand the chain's behavior. If set to False, it will suppress the verbose output – defaults to `False`. - **verbose:** This parameter is used to control the level of detail in the output of the chain. When set to True, it will print out some internal states of the chain while it is being run, which can help debug and understand the chain's behavior. If set to False, it will suppress the verbose output – defaults to `False`.
---
### QianfanLLMEndpoint
Wrapper around [Baidu Qianfan](https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html) large language models.
:::info
The Qianfan Big Model Platform is a one-stop platform for enterprise developers to develop and operate large models and services. It provides data management based on ERNIE Bot's underlying model (Ernie Bot), automatic model customization and fine-tuning, and one-stop large-scale model customization services for cloud deployment of prediction services, and provides ERNIE Bot's enterprise level service API that can be quickly called, helping to implement the demand for generative AI applications in various industries.
:::
- **Model Name:** Model name. you could get from https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu preset models are mapping to an endpoint. `Model Name` will be ignored if `Endpoint` is set.
- **Qianfan Ak:** which you could get from https://cloud.baidu.com/product/wenxinworkshop.
- **Qianfan Sk:** which you could get from https://cloud.baidu.com/product/wenxinworkshop.
- **Top p:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. The diversity of the output text is affected, and the larger the value, the stronger the diversity of the generated text - defaults to `0.8`.
- **Temperature:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. Higher values make the output more random, while lower values make it more concentrated and deterministic - defaults to `0.95`.
- **Penalty Score:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. By increasing the penalty for generated tokens, the phenomenon of duplicate generation is reduced. A higher value indicates a higher penalty - defaults to `1.0`.
- **Endpoint:** Endpoint of the Qianfan LLM, required if custom model used.
---
### QianfanChatEndpoint
Wrapper around [Baidu Qianfan](https://cloud.baidu.com/doc/WENXINWORKSHOP/index.html) chat large language models. This component supports some of the LLMs (Large Language Models) available by Baidu qianfan and is used for tasks such as chatbots, Generative Question-Answering (GQA), and summarization.
:::info
The Qianfan Big Model Platform is a one-stop platform for enterprise developers to develop and operate large models and services. It provides data management based on ERNIE Bot's underlying model (Ernie Bot), automatic model customization and fine-tuning, and one-stop large-scale model customization services for cloud deployment of prediction services, and provides ERNIE Bot's enterprise level service API that can be quickly called, helping to implement the demand for generative AI applications in various industries.
:::
- **Model Name:** Model name. you could get from https://cloud.baidu.com/doc/WENXINWORKSHOP/s/Nlks5zkzu preset models are mapping to an endpoint. `Model Name` will be ignored if `Endpoint` is set.
- **Qianfan Ak:** which you could get from https://cloud.baidu.com/product/wenxinworkshop.
- **Qianfan Sk:** which you could get from https://cloud.baidu.com/product/wenxinworkshop.
- **Top p:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. The diversity of the output text is affected, and the larger the value, the stronger the diversity of the generated text - defaults to `0.8`.
- **Temperature:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. Higher values make the output more random, while lower values make it more concentrated and deterministic - defaults to `0.95`.
- **Penalty Score:** Model params, only supported in ERNIE-Bot and ERNIE-Bot-turbo. By increasing the penalty for generated tokens, the phenomenon of duplicate generation is reduced. A higher value indicates a higher penalty - defaults to `1.0`.
- **Endpoint:** Endpoint of the Qianfan LLM, required if custom model used.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2 MiB

After

Width:  |  Height:  |  Size: 2 MiB

Before After
Before After

167
poetry.lock generated
View file

@ -167,17 +167,17 @@ files = [
[[package]] [[package]]
name = "anthropic" name = "anthropic"
version = "0.7.7" version = "0.7.8"
description = "The official Python library for the anthropic API" description = "The official Python library for the anthropic API"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "anthropic-0.7.7-py3-none-any.whl", hash = "sha256:49a4b0194faa958ec156e4d242a3b6e029d91389bbed1fc267b5b903a4cfef0d"}, {file = "anthropic-0.7.8-py3-none-any.whl", hash = "sha256:268db974578e34d1449cd0d22389394f0c61795ace9a101dcde4eab4b98439bf"},
{file = "anthropic-0.7.7.tar.gz", hash = "sha256:781ce7bcf8d377e4077b71a0c9045c2f7947db6f6c9fe70352e2a7838e055e59"}, {file = "anthropic-0.7.8.tar.gz", hash = "sha256:61bc698553b24bc7721cf71db8de50703f3025ea2d14fa4bcb5b1d2bf37f9e40"},
] ]
[package.dependencies] [package.dependencies]
anyio = ">=3.5.0,<4" anyio = ">=3.5.0,<5"
distro = ">=1.7.0,<2" distro = ">=1.7.0,<2"
httpx = ">=0.23.0,<1" httpx = ">=0.23.0,<1"
pydantic = ">=1.9.0,<3" pydantic = ">=1.9.0,<3"
@ -398,32 +398,32 @@ files = [
[[package]] [[package]]
name = "boto3" name = "boto3"
version = "1.33.12" version = "1.34.0"
description = "The AWS SDK for Python" description = "The AWS SDK for Python"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.8"
files = [ files = [
{file = "boto3-1.33.12-py3-none-any.whl", hash = "sha256:475efcff30401041e9c348e20613eca90ab14a224e2f978ca80de98ba3499435"}, {file = "boto3-1.34.0-py3-none-any.whl", hash = "sha256:8b3c4d4e720c0ad706590c284b8f30c76de3472c1ce1bac610425f99bf6ab53b"},
{file = "boto3-1.33.12.tar.gz", hash = "sha256:2225edaea2fa17274f62707c12d9f7803c998af7089fe8a1ec8e4f1ebf47677e"}, {file = "boto3-1.34.0.tar.gz", hash = "sha256:c9b400529932ed4652304756528ab235c6730aa5d00cb4d9e4848ce460c82c16"},
] ]
[package.dependencies] [package.dependencies]
botocore = ">=1.33.12,<1.34.0" botocore = ">=1.34.0,<1.35.0"
jmespath = ">=0.7.1,<2.0.0" jmespath = ">=0.7.1,<2.0.0"
s3transfer = ">=0.8.2,<0.9.0" s3transfer = ">=0.9.0,<0.10.0"
[package.extras] [package.extras]
crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
[[package]] [[package]]
name = "botocore" name = "botocore"
version = "1.33.12" version = "1.34.0"
description = "Low-level, data-driven core of boto 3." description = "Low-level, data-driven core of boto 3."
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.8"
files = [ files = [
{file = "botocore-1.33.12-py3-none-any.whl", hash = "sha256:48b9cfb9c5f7f9634a71782f16a324acb522b65856ad46be69efe04c3322b23c"}, {file = "botocore-1.34.0-py3-none-any.whl", hash = "sha256:6ec19f6c9f61c3df22fb3e083940ac7946a3d96128db1f370f10aea702bb157f"},
{file = "botocore-1.33.12.tar.gz", hash = "sha256:067c94fa88583c04ae897d48a11d2be09f280363b8e794b82d78d631d3a3e910"}, {file = "botocore-1.34.0.tar.gz", hash = "sha256:711b406de910585395466ca649bceeea87a04300ddf74d9a2e20727c7f27f2f1"},
] ]
[package.dependencies] [package.dependencies]
@ -913,13 +913,13 @@ testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"]
[[package]] [[package]]
name = "cohere" name = "cohere"
version = "4.37" version = "4.38"
description = "Python SDK for the Cohere API" description = "Python SDK for the Cohere API"
optional = false optional = false
python-versions = ">=3.8,<4.0" python-versions = ">=3.8,<4.0"
files = [ files = [
{file = "cohere-4.37-py3-none-any.whl", hash = "sha256:f3fad3a0f8d86761d4de851dfd2233a1e5c7634a024102212d850bde9c9bb031"}, {file = "cohere-4.38-py3-none-any.whl", hash = "sha256:f0edcf779aa6759dd2f91db37dec7b06303029effbd38fecc4e0f8af36aae757"},
{file = "cohere-4.37.tar.gz", hash = "sha256:788021d9d992c6c31d1985d95cccb277c7265882c4acd7a49b3e47da77b4bec8"}, {file = "cohere-4.38.tar.gz", hash = "sha256:232cde3bb932b154effdab4b78f195032ee2188bf3ae9f1c883a51291307f996"},
] ]
[package.dependencies] [package.dependencies]
@ -2084,13 +2084,13 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0.dev0)"]
[[package]] [[package]]
name = "google-api-python-client" name = "google-api-python-client"
version = "2.110.0" version = "2.111.0"
description = "Google API Client Library for Python" description = "Google API Client Library for Python"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "google-api-python-client-2.110.0.tar.gz", hash = "sha256:1f825e48c7fdc3c96ad6aac179cb73c3755dfff41d16487fa7130e5efcfe7b76"}, {file = "google-api-python-client-2.111.0.tar.gz", hash = "sha256:3a45a53c031478d1c82c7162dd25c9a965247bca6bd438af0838a9d9b8219405"},
{file = "google_api_python_client-2.110.0-py2.py3-none-any.whl", hash = "sha256:55e7ebd6079e34934b6751537eb13447110351ae3792a724a33825d7b671ba13"}, {file = "google_api_python_client-2.111.0-py2.py3-none-any.whl", hash = "sha256:b605adee2d09a843b97a59925757802904679e44e5599708cedb8939900dfbc7"},
] ]
[package.dependencies] [package.dependencies]
@ -2125,13 +2125,13 @@ requests = ["requests (>=2.20.0,<3.0.0.dev0)"]
[[package]] [[package]]
name = "google-auth-httplib2" name = "google-auth-httplib2"
version = "0.1.1" version = "0.2.0"
description = "Google Authentication Library: httplib2 transport" description = "Google Authentication Library: httplib2 transport"
optional = false optional = false
python-versions = "*" python-versions = "*"
files = [ files = [
{file = "google-auth-httplib2-0.1.1.tar.gz", hash = "sha256:c64bc555fdc6dd788ea62ecf7bccffcf497bf77244887a3f3d7a5a02f8e3fc29"}, {file = "google-auth-httplib2-0.2.0.tar.gz", hash = "sha256:38aa7badf48f974f1eb9861794e9c0cb2a0511a4ec0679b1f886d108f5640e05"},
{file = "google_auth_httplib2-0.1.1-py2.py3-none-any.whl", hash = "sha256:42c50900b8e4dcdf8222364d1f0efe32b8421fb6ed72f2613f12f75cc933478c"}, {file = "google_auth_httplib2-0.2.0-py2.py3-none-any.whl", hash = "sha256:b65a0a2123300dd71281a7bf6e64d65a0759287df52729bdd1ae2e47dc311a3d"},
] ]
[package.dependencies] [package.dependencies]
@ -2140,13 +2140,13 @@ httplib2 = ">=0.19.0"
[[package]] [[package]]
name = "google-cloud-aiplatform" name = "google-cloud-aiplatform"
version = "1.37.0" version = "1.38.0"
description = "Vertex AI API client library" description = "Vertex AI API client library"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "google-cloud-aiplatform-1.37.0.tar.gz", hash = "sha256:51cac0334fc7274142b50363dd10cbb3d303ff6354e5c06a7fb51e1b7db02dfb"}, {file = "google-cloud-aiplatform-1.38.0.tar.gz", hash = "sha256:dff91f79b64e279f0e61dfd63c4e067ba5fa75ef0f4614289bbdca70d086a9e2"},
{file = "google_cloud_aiplatform-1.37.0-py2.py3-none-any.whl", hash = "sha256:9b3d6e681084a60b7e4de7063d41ca2d354b3546a918609ddaf9d8d1f8b19c36"}, {file = "google_cloud_aiplatform-1.38.0-py2.py3-none-any.whl", hash = "sha256:7eec50d9a36d43e163f019a1ade9284d4580602a5108738a0ebff8940ea47ce0"},
] ]
[package.dependencies] [package.dependencies]
@ -2244,13 +2244,13 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4
[[package]] [[package]]
name = "google-cloud-storage" name = "google-cloud-storage"
version = "2.13.0" version = "2.14.0"
description = "Google Cloud Storage API client library" description = "Google Cloud Storage API client library"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "google-cloud-storage-2.13.0.tar.gz", hash = "sha256:f62dc4c7b6cd4360d072e3deb28035fbdad491ac3d9b0b1815a12daea10f37c7"}, {file = "google-cloud-storage-2.14.0.tar.gz", hash = "sha256:2d23fcf59b55e7b45336729c148bb1c464468c69d5efbaee30f7201dd90eb97e"},
{file = "google_cloud_storage-2.13.0-py2.py3-none-any.whl", hash = "sha256:ab0bf2e1780a1b74cf17fccb13788070b729f50c252f0c94ada2aae0ca95437d"}, {file = "google_cloud_storage-2.14.0-py2.py3-none-any.whl", hash = "sha256:8641243bbf2a2042c16a6399551fbb13f062cbc9a2de38d6c0bb5426962e9dbd"},
] ]
[package.dependencies] [package.dependencies]
@ -2346,13 +2346,13 @@ testing = ["pytest"]
[[package]] [[package]]
name = "google-resumable-media" name = "google-resumable-media"
version = "2.6.0" version = "2.7.0"
description = "Utilities for Google Media Downloads and Resumable Uploads" description = "Utilities for Google Media Downloads and Resumable Uploads"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.7"
files = [ files = [
{file = "google-resumable-media-2.6.0.tar.gz", hash = "sha256:972852f6c65f933e15a4a210c2b96930763b47197cdf4aa5f5bea435efb626e7"}, {file = "google-resumable-media-2.7.0.tar.gz", hash = "sha256:5f18f5fa9836f4b083162064a1c2c98c17239bfda9ca50ad970ccf905f3e625b"},
{file = "google_resumable_media-2.6.0-py2.py3-none-any.whl", hash = "sha256:fc03d344381970f79eebb632a3c18bb1828593a2dc5572b5f90115ef7d11e81b"}, {file = "google_resumable_media-2.7.0-py2.py3-none-any.whl", hash = "sha256:79543cfe433b63fd81c0844b7803aba1bb8950b47bedf7d980c38fa123937e08"},
] ]
[package.dependencies] [package.dependencies]
@ -3512,13 +3512,13 @@ zookeeper = ["kazoo (>=2.8.0)"]
[[package]] [[package]]
name = "langchain" name = "langchain"
version = "0.0.349" version = "0.0.350"
description = "Building applications with LLMs through composability" description = "Building applications with LLMs through composability"
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langchain-0.0.349-py3-none-any.whl", hash = "sha256:8a0933238945ef713b418d2b9f50e950b3cf8745877c74059525794f191f20e6"}, {file = "langchain-0.0.350-py3-none-any.whl", hash = "sha256:11b605f325a4271a7815baaec05bc7622e3ad1f10f26b05c752cafa27663ed38"},
{file = "langchain-0.0.349.tar.gz", hash = "sha256:c795ffca68349a74b3cf7235441608095178d70069bb37a3d8c9050a14c570c8"}, {file = "langchain-0.0.350.tar.gz", hash = "sha256:f0e68a92d200bb722586688ab7b411b2430bd98ad265ca03b264e7e7acbb6c01"},
] ]
[package.dependencies] [package.dependencies]
@ -3526,8 +3526,8 @@ aiohttp = ">=3.8.3,<4.0.0"
async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""}
dataclasses-json = ">=0.5.7,<0.7" dataclasses-json = ">=0.5.7,<0.7"
jsonpatch = ">=1.33,<2.0" jsonpatch = ">=1.33,<2.0"
langchain-community = ">=0.0.1,<0.1" langchain-community = ">=0.0.2,<0.1"
langchain-core = ">=0.0.13,<0.1" langchain-core = ">=0.1,<0.2"
langsmith = ">=0.0.63,<0.1.0" langsmith = ">=0.0.63,<0.1.0"
numpy = ">=1,<2" numpy = ">=1,<2"
pydantic = ">=1,<3" pydantic = ">=1,<3"
@ -3552,19 +3552,19 @@ text-helpers = ["chardet (>=5.1.0,<6.0.0)"]
[[package]] [[package]]
name = "langchain-community" name = "langchain-community"
version = "0.0.1" version = "0.0.3"
description = "Community contributed LangChain integrations." description = "Community contributed LangChain integrations."
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langchain_community-0.0.1-py3-none-any.whl", hash = "sha256:73119fc356502595862e6056ed2bc447455c1e612df55bac08f9cb8056a4ca29"}, {file = "langchain_community-0.0.3-py3-none-any.whl", hash = "sha256:12930ce0bcc39e86804f15e5a31029f836e694d3169b8b10972702760498cf6b"},
{file = "langchain_community-0.0.1.tar.gz", hash = "sha256:271a959cb3a0efc3e9afb62799588ff6cd774fa333c6d514a9be1d5809fb112b"}, {file = "langchain_community-0.0.3.tar.gz", hash = "sha256:f5df5367504f3ca9c2faed390e2c55a338d236d823c61db4d1b237fbe239b04a"},
] ]
[package.dependencies] [package.dependencies]
aiohttp = ">=3.8.3,<4.0.0" aiohttp = ">=3.8.3,<4.0.0"
dataclasses-json = ">=0.5.7,<0.7" dataclasses-json = ">=0.5.7,<0.7"
langchain-core = ">=0.0.13,<0.1" langchain-core = ">=0.1,<0.2"
langsmith = ">=0.0.63,<0.1.0" langsmith = ">=0.0.63,<0.1.0"
numpy = ">=1,<2" numpy = ">=1,<2"
PyYAML = ">=5.3" PyYAML = ">=5.3"
@ -3578,13 +3578,13 @@ extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.
[[package]] [[package]]
name = "langchain-core" name = "langchain-core"
version = "0.0.13" version = "0.1.0"
description = "Building applications with LLMs through composability" description = "Building applications with LLMs through composability"
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langchain_core-0.0.13-py3-none-any.whl", hash = "sha256:36d33a3d280877fb29a1f0f292b9b02b9ba29bf43fb54090b7364f00d5925459"}, {file = "langchain_core-0.1.0-py3-none-any.whl", hash = "sha256:6b155a175e1f1555860b22333c14161c652b0013e229e7b8a083639c821312a8"},
{file = "langchain_core-0.0.13.tar.gz", hash = "sha256:fcfc13d2c314c0441c8f1f8b79395316df5873c1c7a687c8c5c553b3824840b6"}, {file = "langchain_core-0.1.0.tar.gz", hash = "sha256:4c70aa62905896b65c47a966f87584f72026cbe402655749281df81c794e0d6e"},
] ]
[package.dependencies] [package.dependencies]
@ -3602,18 +3602,18 @@ extended-testing = ["jinja2 (>=3,<4)"]
[[package]] [[package]]
name = "langchain-experimental" name = "langchain-experimental"
version = "0.0.46" version = "0.0.47"
description = "Building applications with LLMs through composability" description = "Building applications with LLMs through composability"
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langchain_experimental-0.0.46-py3-none-any.whl", hash = "sha256:64a71daf8807e6429ae08cf97da3bb3475416546b0d97c8051fe4dab42cb8489"}, {file = "langchain_experimental-0.0.47-py3-none-any.whl", hash = "sha256:d5b6930c4e0a6f280cbb7d327d03d86f555f6168e185a1df64ba4a52b1059f65"},
{file = "langchain_experimental-0.0.46.tar.gz", hash = "sha256:9510ecce974b5722c77dd469cb6c5b9bc82195ca7ae070f4ef835861dc31c0fc"}, {file = "langchain_experimental-0.0.47.tar.gz", hash = "sha256:0fdba89a438287c14fa0632c6adf87acffd55158a2f66c7a12be7721a7882a0e"},
] ]
[package.dependencies] [package.dependencies]
langchain = ">=0.0.349,<0.1" langchain = ">=0.0.350,<0.1"
langchain-core = ">=0.0.13,<0.1" langchain-core = ">=0.1,<0.2"
[package.extras] [package.extras]
extended-testing = ["faker (>=19.3.1,<20.0.0)", "jinja2 (>=3,<4)", "presidio-analyzer (>=2.2.33,<3.0.0)", "presidio-anonymizer (>=2.2.33,<3.0.0)", "sentence-transformers (>=2,<3)", "vowpal-wabbit-next (==0.6.0)"] extended-testing = ["faker (>=19.3.1,<20.0.0)", "jinja2 (>=3,<4)", "presidio-analyzer (>=2.2.33,<3.0.0)", "presidio-anonymizer (>=2.2.33,<3.0.0)", "sentence-transformers (>=2,<3)", "vowpal-wabbit-next (==0.6.0)"]
@ -3634,13 +3634,13 @@ six = "*"
[[package]] [[package]]
name = "langfuse" name = "langfuse"
version = "1.13.2" version = "1.14.0"
description = "A client library for accessing langfuse" description = "A client library for accessing langfuse"
optional = false optional = false
python-versions = ">=3.8.1,<4.0" python-versions = ">=3.8.1,<4.0"
files = [ files = [
{file = "langfuse-1.13.2-py3-none-any.whl", hash = "sha256:f64b857f8985ab7f43519b55ad5fe11d57d0224bc18de4cdbfc9aa981600268d"}, {file = "langfuse-1.14.0-py3-none-any.whl", hash = "sha256:f5af266bbc26223acf69928836d21026611d8a31ad3e54082c0ee364f05e0e50"},
{file = "langfuse-1.13.2.tar.gz", hash = "sha256:3ada040076f2df2fda33ca696fbfa532ea486ff85e27e5eebeb71aba760a5770"}, {file = "langfuse-1.14.0.tar.gz", hash = "sha256:7d76cec5e60e4e603753edf6ade95d360c9e8e373aa069f103aad32059dd82f0"},
] ]
[package.dependencies] [package.dependencies]
@ -3652,6 +3652,7 @@ openai = ">=0.27.8"
pydantic = ">=1.10.7,<3.0" pydantic = ">=1.10.7,<3.0"
python-dateutil = ">=2.8.0,<3.0" python-dateutil = ">=2.8.0,<3.0"
pytz = ">=2023.3,<2024.0" pytz = ">=2023.3,<2024.0"
requests = ">=2.31.0,<3.0"
wrapt = "1.14" wrapt = "1.14"
[package.extras] [package.extras]
@ -3712,13 +3713,13 @@ test = ["httpx (>=0.24.1)", "pytest (>=7.4.0)"]
[[package]] [[package]]
name = "locust" name = "locust"
version = "2.19.1" version = "2.20.0"
description = "Developer friendly load testing framework" description = "Developer friendly load testing framework"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "locust-2.19.1-py3-none-any.whl", hash = "sha256:152d6c9b1d8b842422a9ef352d13529d337d5c4e1e0c0a3e0827c1b5eafb903d"}, {file = "locust-2.20.0-py3-none-any.whl", hash = "sha256:8092dde31c4cfb43b9b40470ffc7c5f95b3a491dfcb813bb50567edec28451dc"},
{file = "locust-2.19.1.tar.gz", hash = "sha256:5c21609b1395833dc0b4bb3ddaaf709a88f6e70950aefce86e11eb5944fe9217"}, {file = "locust-2.20.0.tar.gz", hash = "sha256:b6f78af64bc5066babe54836f796469906cd606b01f34ee788986d0b1fbac99a"},
] ]
[package.dependencies] [package.dependencies]
@ -4659,13 +4660,13 @@ sympy = "*"
[[package]] [[package]]
name = "openai" name = "openai"
version = "1.3.8" version = "1.3.9"
description = "The official Python library for the openai API" description = "The official Python library for the openai API"
optional = false optional = false
python-versions = ">=3.7.1" python-versions = ">=3.7.1"
files = [ files = [
{file = "openai-1.3.8-py3-none-any.whl", hash = "sha256:ac5a17352b96db862390d2e6f51de9f7eb32e733f412467b2f160fbd3d0f2609"}, {file = "openai-1.3.9-py3-none-any.whl", hash = "sha256:d30faeffe5995a2cf6b790c0260a5b59647e81c3a1f3b62f51b5e0a0e52681c9"},
{file = "openai-1.3.8.tar.gz", hash = "sha256:54963ff247abe185aad6ee443820e48ad9f87eb4de970acb2514bc113ced748c"}, {file = "openai-1.3.9.tar.gz", hash = "sha256:6f638d96bc89b4394be1d7b37d312f70a055df1a471c92d4c4b2ae3a70c98cb3"},
] ]
[package.dependencies] [package.dependencies]
@ -5393,13 +5394,13 @@ twisted = ["twisted"]
[[package]] [[package]]
name = "prompt-toolkit" name = "prompt-toolkit"
version = "3.0.41" version = "3.0.43"
description = "Library for building powerful interactive command lines in Python" description = "Library for building powerful interactive command lines in Python"
optional = false optional = false
python-versions = ">=3.7.0" python-versions = ">=3.7.0"
files = [ files = [
{file = "prompt_toolkit-3.0.41-py3-none-any.whl", hash = "sha256:f36fe301fafb7470e86aaf90f036eef600a3210be4decf461a5b1ca8403d3cb2"}, {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"},
{file = "prompt_toolkit-3.0.41.tar.gz", hash = "sha256:941367d97fc815548822aa26c2a269fdc4eb21e9ec05fc5d447cf09bad5d75f0"}, {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"},
] ]
[package.dependencies] [package.dependencies]
@ -7118,39 +7119,39 @@ msg-parse = ["extract-msg (>=0.27)"]
[[package]] [[package]]
name = "ruff" name = "ruff"
version = "0.1.7" version = "0.1.8"
description = "An extremely fast Python linter and code formatter, written in Rust." description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "ruff-0.1.7-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7f80496854fdc65b6659c271d2c26e90d4d401e6a4a31908e7e334fab4645aac"}, {file = "ruff-0.1.8-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7de792582f6e490ae6aef36a58d85df9f7a0cfd1b0d4fe6b4fb51803a3ac96fa"},
{file = "ruff-0.1.7-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:1ea109bdb23c2a4413f397ebd8ac32cb498bee234d4191ae1a310af760e5d287"}, {file = "ruff-0.1.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c8e3255afd186c142eef4ec400d7826134f028a85da2146102a1172ecc7c3696"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0c2de9dd9daf5e07624c24add25c3a490dbf74b0e9bca4145c632457b3b42a"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff78a7583020da124dd0deb835ece1d87bb91762d40c514ee9b67a087940528b"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:69a4bed13bc1d5dabf3902522b5a2aadfebe28226c6269694283c3b0cecb45fd"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd8ee69b02e7bdefe1e5da2d5b6eaaddcf4f90859f00281b2333c0e3a0cc9cd6"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de02ca331f2143195a712983a57137c5ec0f10acc4aa81f7c1f86519e52b92a1"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a05b0ddd7ea25495e4115a43125e8a7ebed0aa043c3d432de7e7d6e8e8cd6448"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:45b38c3f8788a65e6a2cab02e0f7adfa88872696839d9882c13b7e2f35d64c5f"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:e6f08ca730f4dc1b76b473bdf30b1b37d42da379202a059eae54ec7fc1fbcfed"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6c64cb67b2025b1ac6d58e5ffca8f7b3f7fd921f35e78198411237e4f0db8e73"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f35960b02df6b827c1b903091bb14f4b003f6cf102705efc4ce78132a0aa5af3"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dcc6bb2f4df59cb5b4b40ff14be7d57012179d69c6565c1da0d1f013d29951b"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d076717c67b34c162da7c1a5bda16ffc205e0e0072c03745275e7eab888719f"},
{file = "ruff-0.1.7-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2bb4bb6bbe921f6b4f5b6fdd8d8468c940731cb9406f274ae8c5ed7a78c478"}, {file = "ruff-0.1.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6a21ab023124eafb7cef6d038f835cb1155cd5ea798edd8d9eb2f8b84be07d9"},
{file = "ruff-0.1.7-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:276a89bcb149b3d8c1b11d91aa81898fe698900ed553a08129b38d9d6570e717"}, {file = "ruff-0.1.8-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ce697c463458555027dfb194cb96d26608abab920fa85213deb5edf26e026664"},
{file = "ruff-0.1.7-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:90c958fe950735041f1c80d21b42184f1072cc3975d05e736e8d66fc377119ea"}, {file = "ruff-0.1.8-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:db6cedd9ffed55548ab313ad718bc34582d394e27a7875b4b952c2d29c001b26"},
{file = "ruff-0.1.7-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6b05e3b123f93bb4146a761b7a7d57af8cb7384ccb2502d29d736eaade0db519"}, {file = "ruff-0.1.8-py3-none-musllinux_1_2_i686.whl", hash = "sha256:05ffe9dbd278965271252704eddb97b4384bf58b971054d517decfbf8c523f05"},
{file = "ruff-0.1.7-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:290ecab680dce94affebefe0bbca2322a6277e83d4f29234627e0f8f6b4fa9ce"}, {file = "ruff-0.1.8-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5daaeaf00ae3c1efec9742ff294b06c3a2a9db8d3db51ee4851c12ad385cda30"},
{file = "ruff-0.1.7-py3-none-win32.whl", hash = "sha256:416dfd0bd45d1a2baa3b1b07b1b9758e7d993c256d3e51dc6e03a5e7901c7d80"}, {file = "ruff-0.1.8-py3-none-win32.whl", hash = "sha256:e49fbdfe257fa41e5c9e13c79b9e79a23a79bd0e40b9314bc53840f520c2c0b3"},
{file = "ruff-0.1.7-py3-none-win_amd64.whl", hash = "sha256:4af95fd1d3b001fc41325064336db36e3d27d2004cdb6d21fd617d45a172dd96"}, {file = "ruff-0.1.8-py3-none-win_amd64.whl", hash = "sha256:f41f692f1691ad87f51708b823af4bb2c5c87c9248ddd3191c8f088e66ce590a"},
{file = "ruff-0.1.7-py3-none-win_arm64.whl", hash = "sha256:0683b7bfbb95e6df3c7c04fe9d78f631f8e8ba4868dfc932d43d690698057e2e"}, {file = "ruff-0.1.8-py3-none-win_arm64.whl", hash = "sha256:aa8ee4f8440023b0a6c3707f76cadce8657553655dcbb5fc9b2f9bb9bee389f6"},
{file = "ruff-0.1.7.tar.gz", hash = "sha256:dffd699d07abf54833e5f6cc50b85a6ff043715da8788c4a79bcd4ab4734d306"}, {file = "ruff-0.1.8.tar.gz", hash = "sha256:f7ee467677467526cfe135eab86a40a0e8db43117936ac4f9b469ce9cdb3fb62"},
] ]
[[package]] [[package]]
name = "s3transfer" name = "s3transfer"
version = "0.8.2" version = "0.9.0"
description = "An Amazon S3 Transfer Manager" description = "An Amazon S3 Transfer Manager"
optional = false optional = false
python-versions = ">= 3.7" python-versions = ">= 3.8"
files = [ files = [
{file = "s3transfer-0.8.2-py3-none-any.whl", hash = "sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76"}, {file = "s3transfer-0.9.0-py3-none-any.whl", hash = "sha256:01d4d2c35a016db8cb14f9a4d5e84c1f8c96e7ffc211422555eed45c11fa7eb1"},
{file = "s3transfer-0.8.2.tar.gz", hash = "sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283"}, {file = "s3transfer-0.9.0.tar.gz", hash = "sha256:9e1b186ec8bb5907a1e82b51237091889a9973a2bb799a924bcd9f301ff79d3d"},
] ]
[package.dependencies] [package.dependencies]

View file

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "langflow" name = "langflow"
version = "0.6.0rc1" version = "0.6.1"
description = "A Python package with a built-in web application" description = "A Python package with a built-in web application"
authors = ["Logspace <contact@logspace.ai>"] authors = ["Logspace <contact@logspace.ai>"]
maintainers = [ maintainers = [

View file

@ -142,7 +142,7 @@ async def stream_build(
number_of_nodes = len(graph.vertices) number_of_nodes = len(graph.vertices)
update_build_status(cache_service, flow_id, BuildStatus.IN_PROGRESS) update_build_status(cache_service, flow_id, BuildStatus.IN_PROGRESS)
time_elapsed = ""
try: try:
user_id = flow_cache["user_id"] user_id = flow_cache["user_id"]
except KeyError: except KeyError:
@ -175,8 +175,10 @@ async def stream_build(
logger.exception(exc) logger.exception(exc)
params = str(exc) params = str(exc)
valid = False valid = False
time_elapsed = format_elapsed_time(time.perf_counter() - start_time)
update_build_status(cache_service, flow_id, BuildStatus.FAILURE) update_build_status(cache_service, flow_id, BuildStatus.FAILURE)
vertex_id = vertex.parent_node_id if vertex.parent_is_top_level else vertex.id vertex_id = vertex.parent_node_id if vertex.parent_is_top_level else vertex.id
if vertex_id in graph.top_level_vertices: if vertex_id in graph.top_level_vertices:
response = { response = {

View file

@ -5,13 +5,14 @@ from uuid import UUID
import orjson import orjson
from fastapi import APIRouter, Depends, File, HTTPException, UploadFile from fastapi import APIRouter, Depends, File, HTTPException, UploadFile
from fastapi.encoders import jsonable_encoder from fastapi.encoders import jsonable_encoder
from sqlmodel import Session, select
from langflow.api.utils import remove_api_keys, validate_is_component from langflow.api.utils import remove_api_keys, validate_is_component
from langflow.api.v1.schemas import FlowListCreate, FlowListRead from langflow.api.v1.schemas import FlowListCreate, FlowListRead
from langflow.services.auth.utils import get_current_active_user from langflow.services.auth.utils import get_current_active_user
from langflow.services.database.models.flow import Flow, FlowCreate, FlowRead, FlowUpdate from langflow.services.database.models.flow import Flow, FlowCreate, FlowRead, FlowUpdate
from langflow.services.database.models.user.model import User from langflow.services.database.models.user.model import User
from langflow.services.deps import get_session, get_settings_service from langflow.services.deps import get_session, get_settings_service
from sqlmodel import Session, select
# build router # build router
router = APIRouter(prefix="/flows", tags=["Flows"]) router = APIRouter(prefix="/flows", tags=["Flows"])
@ -122,7 +123,7 @@ def create_flows(
db_flows = [] db_flows = []
for flow in flow_list.flows: for flow in flow_list.flows:
flow.user_id = current_user.id flow.user_id = current_user.id
db_flow = Flow.from_orm(flow) db_flow = Flow.model_validate(flow, from_attributes=True)
session.add(db_flow) session.add(db_flow)
db_flows.append(db_flow) db_flows.append(db_flow)
session.commit() session.commit()

View file

@ -1,6 +1,11 @@
from uuid import UUID from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select
from sqlmodel.sql.expression import SelectOfScalar
from langflow.api.v1.schemas import UsersResponse from langflow.api.v1.schemas import UsersResponse
from langflow.services.auth.utils import ( from langflow.services.auth.utils import (
get_current_active_superuser, get_current_active_superuser,
@ -11,10 +16,6 @@ from langflow.services.auth.utils import (
from langflow.services.database.models.user import User, UserCreate, UserRead, UserUpdate from langflow.services.database.models.user import User, UserCreate, UserRead, UserUpdate
from langflow.services.database.models.user.crud import get_user_by_id, update_user from langflow.services.database.models.user.crud import get_user_by_id, update_user
from langflow.services.deps import get_session, get_settings_service from langflow.services.deps import get_session, get_settings_service
from sqlalchemy import func
from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select
from sqlmodel.sql.expression import SelectOfScalar
router = APIRouter(tags=["Users"], prefix="/users") router = APIRouter(tags=["Users"], prefix="/users")
@ -28,7 +29,7 @@ def add_user(
""" """
Add a new user to the database. Add a new user to the database.
""" """
new_user = User.from_orm(user) new_user = User.model_validate(user, from_attributes=True)
try: try:
new_user.password = get_password_hash(user.password) new_user.password = get_password_hash(user.password)
new_user.is_active = settings_service.auth_settings.NEW_USER_IS_ACTIVE new_user.is_active = settings_service.auth_settings.NEW_USER_IS_ACTIVE

View file

@ -1,4 +1,4 @@
from typing import Optional, Union from typing import List, Optional, Union
import chromadb # type: ignore import chromadb # type: ignore
from langchain.embeddings.base import Embeddings from langchain.embeddings.base import Embeddings
@ -56,7 +56,7 @@ class ChromaComponent(CustomComponent):
embedding: Embeddings, embedding: Embeddings,
chroma_server_ssl_enabled: bool, chroma_server_ssl_enabled: bool,
persist_directory: Optional[str] = None, persist_directory: Optional[str] = None,
documents: Optional[Document] = None, documents: Optional[List[Document]] = None,
chroma_server_cors_allow_origins: Optional[str] = None, chroma_server_cors_allow_origins: Optional[str] = None,
chroma_server_host: Optional[str] = None, chroma_server_host: Optional[str] = None,
chroma_server_port: Optional[int] = None, chroma_server_port: Optional[int] = None,

View file

@ -209,15 +209,18 @@ class Graph:
edges.append(Edge(source, target, edge)) edges.append(Edge(source, target, edge))
return edges return edges
def _get_vertex_class(self, vertex_type: str, vertex_lc_type: str) -> Type[Vertex]: def _get_vertex_class(self, vertex_type: str, vertex_base_type: str) -> Type[Vertex]:
"""Returns the vertex class based on the vertex type.""" """Returns the vertex class based on the vertex type."""
if vertex_type in FILE_TOOLS: if vertex_type in FILE_TOOLS:
return FileToolVertex return FileToolVertex
if vertex_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP: if vertex_base_type == "CustomComponent":
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[vertex_type] return lazy_load_vertex_dict.get_custom_component_vertex_type()
if vertex_base_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP:
return lazy_load_vertex_dict.VERTEX_TYPE_MAP[vertex_base_type]
return ( return (
lazy_load_vertex_dict.VERTEX_TYPE_MAP[vertex_lc_type] lazy_load_vertex_dict.VERTEX_TYPE_MAP[vertex_type]
if vertex_lc_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP if vertex_type in lazy_load_vertex_dict.VERTEX_TYPE_MAP
else Vertex else Vertex
) )
@ -227,9 +230,9 @@ class Graph:
for vertex in self._vertices: for vertex in self._vertices:
vertex_data = vertex["data"] vertex_data = vertex["data"]
vertex_type: str = vertex_data["type"] # type: ignore vertex_type: str = vertex_data["type"] # type: ignore
vertex_lc_type: str = vertex_data["node"]["template"]["_type"] # type: ignore vertex_base_type: str = vertex_data["node"]["template"]["_type"] # type: ignore
VertexClass = self._get_vertex_class(vertex_type, vertex_lc_type) VertexClass = self._get_vertex_class(vertex_type, vertex_base_type)
vertex_instance = VertexClass(vertex, graph=self) vertex_instance = VertexClass(vertex, graph=self)
vertex_instance.set_top_level(self.top_level_vertices) vertex_instance.set_top_level(self.top_level_vertices)
vertices.append(vertex_instance) vertices.append(vertex_instance)

View file

@ -1,19 +1,19 @@
from langflow.graph.vertex import types from langflow.graph.vertex import types
from langflow.interface.agents.base import agent_creator from langflow.interface.agents.base import agent_creator
from langflow.interface.chains.base import chain_creator from langflow.interface.chains.base import chain_creator
from langflow.interface.custom.base import custom_component_creator
from langflow.interface.document_loaders.base import documentloader_creator from langflow.interface.document_loaders.base import documentloader_creator
from langflow.interface.embeddings.base import embedding_creator from langflow.interface.embeddings.base import embedding_creator
from langflow.interface.llms.base import llm_creator from langflow.interface.llms.base import llm_creator
from langflow.interface.memories.base import memory_creator from langflow.interface.memories.base import memory_creator
from langflow.interface.output_parsers.base import output_parser_creator
from langflow.interface.prompts.base import prompt_creator from langflow.interface.prompts.base import prompt_creator
from langflow.interface.retrievers.base import retriever_creator
from langflow.interface.text_splitters.base import textsplitter_creator from langflow.interface.text_splitters.base import textsplitter_creator
from langflow.interface.toolkits.base import toolkits_creator from langflow.interface.toolkits.base import toolkits_creator
from langflow.interface.tools.base import tool_creator from langflow.interface.tools.base import tool_creator
from langflow.interface.vector_store.base import vectorstore_creator from langflow.interface.vector_store.base import vectorstore_creator
from langflow.interface.wrappers.base import wrapper_creator from langflow.interface.wrappers.base import wrapper_creator
from langflow.interface.output_parsers.base import output_parser_creator
from langflow.interface.retrievers.base import retriever_creator
from langflow.interface.custom.base import custom_component_creator
from langflow.utils.lazy_load import LazyLoadDictBase from langflow.utils.lazy_load import LazyLoadDictBase
@ -32,6 +32,9 @@ class VertexTypesDict(LazyLoadDictBase):
"Custom": ["Custom Tool", "Python Function"], "Custom": ["Custom Tool", "Python Function"],
} }
def get_custom_component_vertex_type(self):
return types.CustomComponentVertex
def get_type_dict(self): def get_type_dict(self):
return { return {
**{t: types.PromptVertex for t in prompt_creator.to_list()}, **{t: types.PromptVertex for t in prompt_creator.to_list()},

View file

@ -29,7 +29,7 @@ def create_api_key(session: Session, api_key_create: ApiKeyCreate, user_id: UUID
session.add(api_key) session.add(api_key)
session.commit() session.commit()
session.refresh(api_key) session.refresh(api_key)
unmasked = UnmaskedApiKeyRead.from_orm(api_key) unmasked = UnmaskedApiKeyRead.model_validate(api_key, from_attributes=True)
unmasked.api_key = generated_api_key unmasked.api_key = generated_api_key
return unmasked return unmasked

View file

@ -10,15 +10,16 @@ import orjson
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from httpx import AsyncClient from httpx import AsyncClient
from sqlmodel import Session, SQLModel, create_engine
from sqlmodel.pool import StaticPool
from typer.testing import CliRunner
from langflow.graph.graph.base import Graph from langflow.graph.graph.base import Graph
from langflow.services.auth.utils import get_password_hash from langflow.services.auth.utils import get_password_hash
from langflow.services.database.models.flow.model import Flow, FlowCreate from langflow.services.database.models.flow.model import Flow, FlowCreate
from langflow.services.database.models.user.model import User, UserCreate from langflow.services.database.models.user.model import User, UserCreate
from langflow.services.database.utils import session_getter from langflow.services.database.utils import session_getter
from langflow.services.deps import get_db_service from langflow.services.deps import get_db_service
from sqlmodel import Session, SQLModel, create_engine
from sqlmodel.pool import StaticPool
from typer.testing import CliRunner
if TYPE_CHECKING: if TYPE_CHECKING:
from langflow.services.database.service import DatabaseService from langflow.services.database.service import DatabaseService

View file

@ -9,6 +9,7 @@ import pytest
from langchain.agents import AgentExecutor from langchain.agents import AgentExecutor
from langchain.chains.base import Chain from langchain.chains.base import Chain
from langchain.llms.fake import FakeListLLM from langchain.llms.fake import FakeListLLM
from langflow.graph import Graph from langflow.graph import Graph
from langflow.graph.edge.base import Edge from langflow.graph.edge.base import Edge
from langflow.graph.graph.utils import ( from langflow.graph.graph.utils import (
@ -151,6 +152,55 @@ def test_get_node_neighbors_basic(basic_graph):
assert any("OpenAI" in neighbor.data["type"] for neighbor, val in neighbors.items() if val) assert any("OpenAI" in neighbor.data["type"] for neighbor, val in neighbors.items() if val)
# def test_get_node_neighbors_complex(complex_graph):
# """Test getting node neighbors"""
# assert isinstance(complex_graph, Graph)
# # Get root node
# root = get_root_node(complex_graph)
# assert root is not None
# neighbors = complex_graph.get_nodes_with_target(root)
# assert neighbors is not None
# # Neighbors should be a list of nodes
# assert isinstance(neighbors, list)
# # Root Node is an Agent, it requires an LLMChain and tools
# # We need to check if there is a Chain in the one of the neighbors'
# assert any("Chain" in neighbor.data["type"] for neighbor in neighbors)
# # assert Tool is in the neighbors
# assert any("Tool" in neighbor.data["type"] for neighbor in neighbors)
# # Now on to the Chain's neighbors
# chain = next(neighbor for neighbor in neighbors if "Chain" in neighbor.data["type"])
# chain_neighbors = complex_graph.get_nodes_with_target(chain)
# assert chain_neighbors is not None
# # Check if there is a LLM in the chain's neighbors
# assert any("OpenAI" in neighbor.data["type"] for neighbor in chain_neighbors)
# # Chain should have a Prompt as a neighbor
# assert any("Prompt" in neighbor.data["type"] for neighbor in chain_neighbors)
# # Now on to the Tool's neighbors
# tool = next(neighbor for neighbor in neighbors if "Tool" in neighbor.data["type"])
# tool_neighbors = complex_graph.get_nodes_with_target(tool)
# assert tool_neighbors is not None
# # Check if there is an Agent in the tool's neighbors
# assert any("Agent" in neighbor.data["type"] for neighbor in tool_neighbors)
# # This Agent has a Tool that has a PythonFunction as func
# agent = next(
# neighbor for neighbor in tool_neighbors if "Agent" in neighbor.data["type"]
# )
# agent_neighbors = complex_graph.get_nodes_with_target(agent)
# assert agent_neighbors is not None
# # Check if there is a Tool in the agent's neighbors
# assert any("Tool" in neighbor.data["type"] for neighbor in agent_neighbors)
# # This Tool has a PythonFunction as func
# tool = next(
# neighbor for neighbor in agent_neighbors if "Tool" in neighbor.data["type"]
# )
# tool_neighbors = complex_graph.get_nodes_with_target(tool)
# assert tool_neighbors is not None
# # Check if there is a PythonFunction in the tool's neighbors
# assert any(
# "PythonFunctionTool" in neighbor.data["type"] for neighbor in tool_neighbors
# )
def test_get_node(basic_graph): def test_get_node(basic_graph):
"""Test getting a single node""" """Test getting a single node"""
node_id = basic_graph.vertices[0].id node_id = basic_graph.vertices[0].id

View file

@ -1,4 +1,5 @@
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from langflow.services.deps import get_settings_service from langflow.services.deps import get_settings_service

View file

@ -2,6 +2,8 @@ import importlib
from typing import Dict, List, Optional from typing import Dict, List, Optional
import pytest import pytest
from pydantic import BaseModel
from langflow.utils.constants import CHAT_OPENAI_MODELS, OPENAI_MODELS from langflow.utils.constants import CHAT_OPENAI_MODELS, OPENAI_MODELS
from langflow.utils.util import ( from langflow.utils.util import (
build_template_from_class, build_template_from_class,
@ -10,7 +12,6 @@ from langflow.utils.util import (
get_base_classes, get_base_classes,
get_default_factory, get_default_factory,
) )
from pydantic import BaseModel
# Dummy classes for testing purposes # Dummy classes for testing purposes