From 34b6153fed85bbfa5d94777e2631283c177c3fa4 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 13 Jun 2024 06:52:32 -0700 Subject: [PATCH 01/13] chore: Update persist_directory parameter to handle None value in ChromaSearch and Chroma components (#2157) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: Update persist_directory parameter to handle None value in ChromaSearch and Chroma components * 🐛 (test_endpoints.py): fix assertion to check for correct key name in output results for chat and any input types --- .../base/langflow/components/vectorsearch/ChromaSearch.py | 4 ++-- src/backend/base/langflow/components/vectorstores/Chroma.py | 3 +-- tests/test_endpoints.py | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py b/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py index 228e100e4..3d4687522 100644 --- a/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py +++ b/src/backend/base/langflow/components/vectorsearch/ChromaSearch.py @@ -3,7 +3,6 @@ from typing import List, Optional import chromadb from chromadb.config import Settings from langchain_chroma import Chroma - from langflow.components.vectorstores.base.model import LCVectorStoreComponent from langflow.field_typing import Embeddings, Text from langflow.schema import Record @@ -104,10 +103,11 @@ class ChromaSearchComponent(LCVectorStoreComponent): client = chromadb.HttpClient(settings=chroma_settings) if index_directory: index_directory = self.resolve_path(index_directory) + vector_store = Chroma( embedding_function=embedding, collection_name=collection_name, - persist_directory=index_directory, + persist_directory=index_directory or None, client=client, ) diff --git a/src/backend/base/langflow/components/vectorstores/Chroma.py b/src/backend/base/langflow/components/vectorstores/Chroma.py index 6001b119c..f7080d2fc 100644 --- a/src/backend/base/langflow/components/vectorstores/Chroma.py +++ b/src/backend/base/langflow/components/vectorstores/Chroma.py @@ -7,7 +7,6 @@ from langchain_chroma import Chroma from langchain_core.embeddings import Embeddings from langchain_core.retrievers import BaseRetriever from langchain_core.vectorstores import VectorStore - from langflow.base.vectorstores.utils import chroma_collection_to_records from langflow.custom import CustomComponent from langflow.schema import Record @@ -107,7 +106,7 @@ class ChromaComponent(CustomComponent): index_directory = self.resolve_path(index_directory) chroma = Chroma( - persist_directory=index_directory, + persist_directory=index_directory or None, client=client, embedding_function=embedding, collection_name=collection_name, diff --git a/tests/test_endpoints.py b/tests/test_endpoints.py index d7c8a4ef2..1f1dcd5df 100644 --- a/tests/test_endpoints.py +++ b/tests/test_endpoints.py @@ -597,7 +597,7 @@ def test_successful_run_with_input_type_chat(client, starter_project, created_ap chat_input_outputs = [output for output in outputs_dict.get("outputs") if "ChatInput" in output.get("component_id")] assert len(chat_input_outputs) == 1 # Now we check if the input_value is correct - assert all([output.get("results").get("result") == "value1" for output in chat_input_outputs]), chat_input_outputs + assert all([output.get("results").get("text") == "value1" for output in chat_input_outputs]), chat_input_outputs def test_successful_run_with_input_type_any(client, starter_project, created_api_key): @@ -631,7 +631,7 @@ def test_successful_run_with_input_type_any(client, starter_project, created_api ] assert len(any_input_outputs) == 1 # Now we check if the input_value is correct - assert all([output.get("results").get("result") == "value1" for output in any_input_outputs]), any_input_outputs + assert all([output.get("results").get("text") == "value1" for output in any_input_outputs]), any_input_outputs @pytest.mark.api_key_required From 18b95c5092320e014cf353bb73be3e78acc945df Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 13 Jun 2024 07:27:15 -0700 Subject: [PATCH 02/13] chore: Update duckdb dependency to version 1.0.0 and improve MonitorService code (#2158) --- poetry.lock | 103 +++++++++--------- .../base/langflow/services/monitor/service.py | 27 +++-- src/backend/base/poetry.lock | 103 +++++++++--------- src/backend/base/pyproject.toml | 2 +- 4 files changed, 116 insertions(+), 119 deletions(-) diff --git a/poetry.lock b/poetry.lock index 29144c27b..4701d9fb2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1767,58 +1767,57 @@ weaviate = ["weaviate-client (>=3.26.1,<3.27.0)", "weaviate-client (>=4.5.4,<4.6 [[package]] name = "duckdb" -version = "0.10.3" +version = "1.0.0" description = "DuckDB in-process database" optional = false python-versions = ">=3.7.0" files = [ - {file = "duckdb-0.10.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd25cc8d001c09a19340739ba59d33e12a81ab285b7a6bed37169655e1cefb31"}, - {file = "duckdb-0.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f9259c637b917ca0f4c63887e8d9b35ec248f5d987c886dfc4229d66a791009"}, - {file = "duckdb-0.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b48f5f1542f1e4b184e6b4fc188f497be8b9c48127867e7d9a5f4a3e334f88b0"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e327f7a3951ea154bb56e3fef7da889e790bd9a67ca3c36afc1beb17d3feb6d6"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d8b20ed67da004b4481973f4254fd79a0e5af957d2382eac8624b5c527ec48c"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d37680b8d7be04e4709db3a66c8b3eb7ceba2a5276574903528632f2b2cc2e60"}, - {file = "duckdb-0.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d34b86d6a2a6dfe8bb757f90bfe7101a3bd9e3022bf19dbddfa4b32680d26a9"}, - {file = "duckdb-0.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:73b1cb283ca0f6576dc18183fd315b4e487a545667ffebbf50b08eb4e8cdc143"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d917dde19fcec8cadcbef1f23946e85dee626ddc133e1e3f6551f15a61a03c61"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46757e0cf5f44b4cb820c48a34f339a9ccf83b43d525d44947273a585a4ed822"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:338c14d8ac53ac4aa9ec03b6f1325ecfe609ceeb72565124d489cb07f8a1e4eb"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:651fcb429602b79a3cf76b662a39e93e9c3e6650f7018258f4af344c816dab72"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3ae3c73b98b6215dab93cc9bc936b94aed55b53c34ba01dec863c5cab9f8e25"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56429b2cfe70e367fb818c2be19f59ce2f6b080c8382c4d10b4f90ba81f774e9"}, - {file = "duckdb-0.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b46c02c2e39e3676b1bb0dc7720b8aa953734de4fd1b762e6d7375fbeb1b63af"}, - {file = "duckdb-0.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:bcd460feef56575af2c2443d7394d405a164c409e9794a4d94cb5fdaa24a0ba4"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e229a7c6361afbb0d0ab29b1b398c10921263c52957aefe3ace99b0426fdb91e"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:732b1d3b6b17bf2f32ea696b9afc9e033493c5a3b783c292ca4b0ee7cc7b0e66"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5380d4db11fec5021389fb85d614680dc12757ef7c5881262742250e0b58c75"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:468a4e0c0b13c55f84972b1110060d1b0f854ffeb5900a178a775259ec1562db"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fa1e7ff8d18d71defa84e79f5c86aa25d3be80d7cb7bc259a322de6d7cc72da"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed1063ed97c02e9cf2e7fd1d280de2d1e243d72268330f45344c69c7ce438a01"}, - {file = "duckdb-0.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:22f2aad5bb49c007f3bfcd3e81fdedbc16a2ae41f2915fc278724ca494128b0c"}, - {file = "duckdb-0.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:8f9e2bb00a048eb70b73a494bdc868ce7549b342f7ffec88192a78e5a4e164bd"}, - {file = "duckdb-0.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6c2fc49875b4b54e882d68703083ca6f84b27536d57d623fc872e2f502b1078"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66c125d0c30af210f7ee599e7821c3d1a7e09208196dafbf997d4e0cfcb81ab"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99dd7a1d901149c7a276440d6e737b2777e17d2046f5efb0c06ad3b8cb066a6"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ec3bbdb209e6095d202202893763e26c17c88293b88ef986b619e6c8b6715bd"}, - {file = "duckdb-0.10.3-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:2b3dec4ef8ed355d7b7230b40950b30d0def2c387a2e8cd7efc80b9d14134ecf"}, - {file = "duckdb-0.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:04129f94fb49bba5eea22f941f0fb30337f069a04993048b59e2811f52d564bc"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d75d67024fc22c8edfd47747c8550fb3c34fb1cbcbfd567e94939ffd9c9e3ca7"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3796e9507c02d0ddbba2e84c994fae131da567ce3d9cbb4cbcd32fadc5fbb26"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:78e539d85ebd84e3e87ec44d28ad912ca4ca444fe705794e0de9be3dd5550c11"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a99b67ac674b4de32073e9bc604b9c2273d399325181ff50b436c6da17bf00a"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1209a354a763758c4017a1f6a9f9b154a83bed4458287af9f71d84664ddb86b6"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b735cea64aab39b67c136ab3a571dbf834067f8472ba2f8bf0341bc91bea820"}, - {file = "duckdb-0.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:816ffb9f758ed98eb02199d9321d592d7a32a6cb6aa31930f4337eb22cfc64e2"}, - {file = "duckdb-0.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:1631184b94c3dc38b13bce4045bf3ae7e1b0ecbfbb8771eb8d751d8ffe1b59b3"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb98c35fc8dd65043bc08a2414dd9f59c680d7e8656295b8969f3f2061f26c52"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e75c9f5b6a92b2a6816605c001d30790f6d67ce627a2b848d4d6040686efdf9"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae786eddf1c2fd003466e13393b9348a44b6061af6fe7bcb380a64cac24e7df7"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9387da7b7973707b0dea2588749660dd5dd724273222680e985a2dd36787668"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:538f943bf9fa8a3a7c4fafa05f21a69539d2c8a68e557233cbe9d989ae232899"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6930608f35025a73eb94252964f9f19dd68cf2aaa471da3982cf6694866cfa63"}, - {file = "duckdb-0.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:03bc54a9cde5490918aad82d7d2a34290e3dfb78d5b889c6626625c0f141272a"}, - {file = "duckdb-0.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:372b6e3901d85108cafe5df03c872dfb6f0dbff66165a0cf46c47246c1957aa0"}, - {file = "duckdb-0.10.3.tar.gz", hash = "sha256:c5bd84a92bc708d3a6adffe1f554b94c6e76c795826daaaf482afc3d9c636971"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4a8ce2d1f9e1c23b9bab3ae4ca7997e9822e21563ff8f646992663f66d050211"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:19797670f20f430196e48d25d082a264b66150c264c1e8eae8e22c64c2c5f3f5"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:b71c342090fe117b35d866a91ad6bffce61cd6ff3e0cff4003f93fc1506da0d8"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dd69f44ad212c35ae2ea736b0e643ea2b70f204b8dff483af1491b0e2a4cec"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8da5f293ecb4f99daa9a9352c5fd1312a6ab02b464653a0c3a25ab7065c45d4d"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3207936da9967ddbb60644ec291eb934d5819b08169bc35d08b2dedbe7068c60"}, + {file = "duckdb-1.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1128d6c9c33e883b1f5df6b57c1eb46b7ab1baf2650912d77ee769aaa05111f9"}, + {file = "duckdb-1.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:02310d263474d0ac238646677feff47190ffb82544c018b2ff732a4cb462c6ef"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:75586791ab2702719c284157b65ecefe12d0cca9041da474391896ddd9aa71a4"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:83bb415fc7994e641344f3489e40430ce083b78963cb1057bf714ac3a58da3ba"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:bee2e0b415074e84c5a2cefd91f6b5ebeb4283e7196ba4ef65175a7cef298b57"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa5a4110d2a499312609544ad0be61e85a5cdad90e5b6d75ad16b300bf075b90"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa389e6a382d4707b5f3d1bc2087895925ebb92b77e9fe3bfb23c9b98372fdc"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ede6f5277dd851f1a4586b0c78dc93f6c26da45e12b23ee0e88c76519cbdbe0"}, + {file = "duckdb-1.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0b88cdbc0d5c3e3d7545a341784dc6cafd90fc035f17b2f04bf1e870c68456e5"}, + {file = "duckdb-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd1693cdd15375156f7fff4745debc14e5c54928589f67b87fb8eace9880c370"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c65a7fe8a8ce21b985356ee3ec0c3d3b3b2234e288e64b4cfb03356dbe6e5583"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:e5a8eda554379b3a43b07bad00968acc14dd3e518c9fbe8f128b484cf95e3d16"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:a1b6acdd54c4a7b43bd7cb584975a1b2ff88ea1a31607a2b734b17960e7d3088"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a677bb1b6a8e7cab4a19874249d8144296e6e39dae38fce66a80f26d15e670df"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:752e9d412b0a2871bf615a2ede54be494c6dc289d076974eefbf3af28129c759"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3aadb99d098c5e32d00dc09421bc63a47134a6a0de9d7cd6abf21780b678663c"}, + {file = "duckdb-1.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83b7091d4da3e9301c4f9378833f5ffe934fb1ad2b387b439ee067b2c10c8bb0"}, + {file = "duckdb-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:6a8058d0148b544694cb5ea331db44f6c2a00a7b03776cc4dd1470735c3d5ff7"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40cb20e5ee19d44bc66ec99969af791702a049079dc5f248c33b1c56af055f4"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7bce1bc0de9af9f47328e24e6e7e39da30093179b1c031897c042dd94a59c8e"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8355507f7a04bc0a3666958f4414a58e06141d603e91c0fa5a7c50e49867fb6d"}, + {file = "duckdb-1.0.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:39f1a46f5a45ad2886dc9b02ce5b484f437f90de66c327f86606d9ba4479d475"}, + {file = "duckdb-1.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d29ba477b27ae41676b62c8fae8d04ee7cbe458127a44f6049888231ca58fa"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:1bea713c1925918714328da76e79a1f7651b2b503511498ccf5e007a7e67d49e"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_universal2.whl", hash = "sha256:bfe67f3bcf181edbf6f918b8c963eb060e6aa26697d86590da4edc5707205450"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:dbc6093a75242f002be1d96a6ace3fdf1d002c813e67baff52112e899de9292f"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba1881a2b11c507cee18f8fd9ef10100be066fddaa2c20fba1f9a664245cd6d8"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:445d0bb35087c522705c724a75f9f1c13f1eb017305b694d2686218d653c8142"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:224553432e84432ffb9684f33206572477049b371ce68cc313a01e214f2fbdda"}, + {file = "duckdb-1.0.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d3914032e47c4e76636ad986d466b63fdea65e37be8a6dfc484ed3f462c4fde4"}, + {file = "duckdb-1.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:af9128a2eb7e1bb50cd2c2020d825fb2946fdad0a2558920cd5411d998999334"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:dd2659a5dbc0df0de68f617a605bf12fe4da85ba24f67c08730984a0892087e8"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:ac5a4afb0bc20725e734e0b2c17e99a274de4801aff0d4e765d276b99dad6d90"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:2c5a53bee3668d6e84c0536164589d5127b23d298e4c443d83f55e4150fafe61"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b980713244d7708b25ee0a73de0c65f0e5521c47a0e907f5e1b933d79d972ef6"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cbd4f9fe7b7a56eff96c3f4d6778770dd370469ca2212eddbae5dd63749db5"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed228167c5d49888c5ef36f6f9cbf65011c2daf9dcb53ea8aa7a041ce567b3e4"}, + {file = "duckdb-1.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46d8395fbcea7231fd5032a250b673cc99352fef349b718a23dea2c0dd2b8dec"}, + {file = "duckdb-1.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:6ad1fc1a4d57e7616944166a5f9417bdbca1ea65c490797e3786e3a42e162d8a"}, + {file = "duckdb-1.0.0.tar.gz", hash = "sha256:a2a059b77bc7d5b76ae9d88e267372deff19c291048d59450c431e166233d453"}, ] [[package]] @@ -4392,7 +4391,7 @@ bcrypt = "4.0.1" cachetools = "^5.3.1" cryptography = "^42.0.5" docstring-parser = "^0.15" -duckdb = "^0.10.2" +duckdb = "^1.0.0" emoji = "^2.12.0" fastapi = "^0.111.0" gunicorn = "^22.0.0" @@ -6935,13 +6934,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.3.2" +version = "2.3.3" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.3.2-py3-none-any.whl", hash = "sha256:ae06e44349e4c7bff8d57aff415dfd397ae75c217a098d54e9e6990ad7594ac7"}, - {file = "pydantic_settings-2.3.2.tar.gz", hash = "sha256:05d33003c74c2cd585de97b59eb17b6ed67181bc8a3ce594d74b5d24e4df7323"}, + {file = "pydantic_settings-2.3.3-py3-none-any.whl", hash = "sha256:e4ed62ad851670975ec11285141db888fd24947f9440bd4380d7d8788d4965de"}, + {file = "pydantic_settings-2.3.3.tar.gz", hash = "sha256:87fda838b64b5039b970cd47c3e8a1ee460ce136278ff672980af21516f6e6ce"}, ] [package.dependencies] diff --git a/src/backend/base/langflow/services/monitor/service.py b/src/backend/base/langflow/services/monitor/service.py index 949877f4c..92c642e20 100644 --- a/src/backend/base/langflow/services/monitor/service.py +++ b/src/backend/base/langflow/services/monitor/service.py @@ -1,14 +1,13 @@ from datetime import datetime from pathlib import Path -from typing import TYPE_CHECKING, Optional, Union, List +from typing import TYPE_CHECKING, List, Optional, Union import duckdb -from loguru import logger -from platformdirs import user_cache_dir - from langflow.services.base import Service from langflow.services.monitor.schema import MessageModel, TransactionModel, VertexBuildModel from langflow.services.monitor.utils import add_row_to_table, drop_and_create_table_if_schema_mismatch +from loguru import logger +from platformdirs import user_cache_dir if TYPE_CHECKING: from langflow.services.settings.manager import SettingsService @@ -32,8 +31,8 @@ class MonitorService(Service): except Exception as e: logger.exception(f"Error initializing monitor service: {e}") - def exec_query(self, query: str): - with duckdb.connect(str(self.db_path)) as conn: + def exec_query(self, query: str, read_only: bool = False): + with duckdb.connect(str(self.db_path), read_only=read_only) as conn: return conn.execute(query).df() def to_df(self, table_name): @@ -55,7 +54,7 @@ class MonitorService(Service): raise ValueError(f"Unknown table name: {table_name}") # Connect to DuckDB and add the row - with duckdb.connect(str(self.db_path)) as conn: + with duckdb.connect(str(self.db_path), read_only=False) as conn: add_row_to_table(conn, table_name, model, data) def load_table_as_dataframe(self, table_name): @@ -89,7 +88,7 @@ class MonitorService(Service): if order_by: query += f" ORDER BY {order_by}" - with duckdb.connect(str(self.db_path)) as conn: + with duckdb.connect(str(self.db_path), read_only=True) as conn: df = conn.execute(query).df() return df.to_dict(orient="records") @@ -99,13 +98,13 @@ class MonitorService(Service): if flow_id: query += f" WHERE flow_id = '{flow_id}'" - with duckdb.connect(str(self.db_path)) as conn: + with duckdb.connect(str(self.db_path), read_only=False) as conn: conn.execute(query) def delete_messages_session(self, session_id: str): query = f"DELETE FROM messages WHERE session_id = '{session_id}'" - return self.exec_query(query) + return self.exec_query(query, read_only=False) def delete_messages(self, message_ids: Union[List[int], str]): if isinstance(message_ids, list): @@ -119,14 +118,14 @@ class MonitorService(Service): query = f"DELETE FROM messages WHERE index IN ({ids_str})" - return self.exec_query(query) + return self.exec_query(query, read_only=False) def update_message(self, message_id: str, **kwargs): query = ( f"""UPDATE messages SET {', '.join(f"{k} = '{v}'" for k, v in kwargs.items())} WHERE index = {message_id}""" ) - return self.exec_query(query) + return self.exec_query(query, read_only=False) def add_message(self, message: MessageModel): self.add_row("messages", message) @@ -162,7 +161,7 @@ class MonitorService(Service): if limit is not None: query += f" LIMIT {limit}" - with duckdb.connect(str(self.db_path)) as conn: + with duckdb.connect(str(self.db_path), read_only=True) as conn: df = conn.execute(query).df() return df @@ -193,7 +192,7 @@ class MonitorService(Service): if order_by: query += f" ORDER BY {order_by} DESC" - with duckdb.connect(str(self.db_path)) as conn: + with duckdb.connect(str(self.db_path), read_only=True) as conn: df = conn.execute(query).df() return df.to_dict(orient="records") diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index e6d42312d..ab30d8f08 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -578,58 +578,57 @@ files = [ [[package]] name = "duckdb" -version = "0.10.3" +version = "1.0.0" description = "DuckDB in-process database" optional = false python-versions = ">=3.7.0" files = [ - {file = "duckdb-0.10.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd25cc8d001c09a19340739ba59d33e12a81ab285b7a6bed37169655e1cefb31"}, - {file = "duckdb-0.10.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2f9259c637b917ca0f4c63887e8d9b35ec248f5d987c886dfc4229d66a791009"}, - {file = "duckdb-0.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b48f5f1542f1e4b184e6b4fc188f497be8b9c48127867e7d9a5f4a3e334f88b0"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e327f7a3951ea154bb56e3fef7da889e790bd9a67ca3c36afc1beb17d3feb6d6"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d8b20ed67da004b4481973f4254fd79a0e5af957d2382eac8624b5c527ec48c"}, - {file = "duckdb-0.10.3-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d37680b8d7be04e4709db3a66c8b3eb7ceba2a5276574903528632f2b2cc2e60"}, - {file = "duckdb-0.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3d34b86d6a2a6dfe8bb757f90bfe7101a3bd9e3022bf19dbddfa4b32680d26a9"}, - {file = "duckdb-0.10.3-cp310-cp310-win_amd64.whl", hash = "sha256:73b1cb283ca0f6576dc18183fd315b4e487a545667ffebbf50b08eb4e8cdc143"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d917dde19fcec8cadcbef1f23946e85dee626ddc133e1e3f6551f15a61a03c61"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46757e0cf5f44b4cb820c48a34f339a9ccf83b43d525d44947273a585a4ed822"}, - {file = "duckdb-0.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:338c14d8ac53ac4aa9ec03b6f1325ecfe609ceeb72565124d489cb07f8a1e4eb"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:651fcb429602b79a3cf76b662a39e93e9c3e6650f7018258f4af344c816dab72"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3ae3c73b98b6215dab93cc9bc936b94aed55b53c34ba01dec863c5cab9f8e25"}, - {file = "duckdb-0.10.3-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56429b2cfe70e367fb818c2be19f59ce2f6b080c8382c4d10b4f90ba81f774e9"}, - {file = "duckdb-0.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b46c02c2e39e3676b1bb0dc7720b8aa953734de4fd1b762e6d7375fbeb1b63af"}, - {file = "duckdb-0.10.3-cp311-cp311-win_amd64.whl", hash = "sha256:bcd460feef56575af2c2443d7394d405a164c409e9794a4d94cb5fdaa24a0ba4"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:e229a7c6361afbb0d0ab29b1b398c10921263c52957aefe3ace99b0426fdb91e"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:732b1d3b6b17bf2f32ea696b9afc9e033493c5a3b783c292ca4b0ee7cc7b0e66"}, - {file = "duckdb-0.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5380d4db11fec5021389fb85d614680dc12757ef7c5881262742250e0b58c75"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:468a4e0c0b13c55f84972b1110060d1b0f854ffeb5900a178a775259ec1562db"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fa1e7ff8d18d71defa84e79f5c86aa25d3be80d7cb7bc259a322de6d7cc72da"}, - {file = "duckdb-0.10.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed1063ed97c02e9cf2e7fd1d280de2d1e243d72268330f45344c69c7ce438a01"}, - {file = "duckdb-0.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:22f2aad5bb49c007f3bfcd3e81fdedbc16a2ae41f2915fc278724ca494128b0c"}, - {file = "duckdb-0.10.3-cp312-cp312-win_amd64.whl", hash = "sha256:8f9e2bb00a048eb70b73a494bdc868ce7549b342f7ffec88192a78e5a4e164bd"}, - {file = "duckdb-0.10.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6c2fc49875b4b54e882d68703083ca6f84b27536d57d623fc872e2f502b1078"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a66c125d0c30af210f7ee599e7821c3d1a7e09208196dafbf997d4e0cfcb81ab"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d99dd7a1d901149c7a276440d6e737b2777e17d2046f5efb0c06ad3b8cb066a6"}, - {file = "duckdb-0.10.3-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5ec3bbdb209e6095d202202893763e26c17c88293b88ef986b619e6c8b6715bd"}, - {file = "duckdb-0.10.3-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:2b3dec4ef8ed355d7b7230b40950b30d0def2c387a2e8cd7efc80b9d14134ecf"}, - {file = "duckdb-0.10.3-cp37-cp37m-win_amd64.whl", hash = "sha256:04129f94fb49bba5eea22f941f0fb30337f069a04993048b59e2811f52d564bc"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:d75d67024fc22c8edfd47747c8550fb3c34fb1cbcbfd567e94939ffd9c9e3ca7"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f3796e9507c02d0ddbba2e84c994fae131da567ce3d9cbb4cbcd32fadc5fbb26"}, - {file = "duckdb-0.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:78e539d85ebd84e3e87ec44d28ad912ca4ca444fe705794e0de9be3dd5550c11"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a99b67ac674b4de32073e9bc604b9c2273d399325181ff50b436c6da17bf00a"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1209a354a763758c4017a1f6a9f9b154a83bed4458287af9f71d84664ddb86b6"}, - {file = "duckdb-0.10.3-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3b735cea64aab39b67c136ab3a571dbf834067f8472ba2f8bf0341bc91bea820"}, - {file = "duckdb-0.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:816ffb9f758ed98eb02199d9321d592d7a32a6cb6aa31930f4337eb22cfc64e2"}, - {file = "duckdb-0.10.3-cp38-cp38-win_amd64.whl", hash = "sha256:1631184b94c3dc38b13bce4045bf3ae7e1b0ecbfbb8771eb8d751d8ffe1b59b3"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fb98c35fc8dd65043bc08a2414dd9f59c680d7e8656295b8969f3f2061f26c52"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e75c9f5b6a92b2a6816605c001d30790f6d67ce627a2b848d4d6040686efdf9"}, - {file = "duckdb-0.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ae786eddf1c2fd003466e13393b9348a44b6061af6fe7bcb380a64cac24e7df7"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9387da7b7973707b0dea2588749660dd5dd724273222680e985a2dd36787668"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:538f943bf9fa8a3a7c4fafa05f21a69539d2c8a68e557233cbe9d989ae232899"}, - {file = "duckdb-0.10.3-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6930608f35025a73eb94252964f9f19dd68cf2aaa471da3982cf6694866cfa63"}, - {file = "duckdb-0.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:03bc54a9cde5490918aad82d7d2a34290e3dfb78d5b889c6626625c0f141272a"}, - {file = "duckdb-0.10.3-cp39-cp39-win_amd64.whl", hash = "sha256:372b6e3901d85108cafe5df03c872dfb6f0dbff66165a0cf46c47246c1957aa0"}, - {file = "duckdb-0.10.3.tar.gz", hash = "sha256:c5bd84a92bc708d3a6adffe1f554b94c6e76c795826daaaf482afc3d9c636971"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4a8ce2d1f9e1c23b9bab3ae4ca7997e9822e21563ff8f646992663f66d050211"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:19797670f20f430196e48d25d082a264b66150c264c1e8eae8e22c64c2c5f3f5"}, + {file = "duckdb-1.0.0-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:b71c342090fe117b35d866a91ad6bffce61cd6ff3e0cff4003f93fc1506da0d8"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25dd69f44ad212c35ae2ea736b0e643ea2b70f204b8dff483af1491b0e2a4cec"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8da5f293ecb4f99daa9a9352c5fd1312a6ab02b464653a0c3a25ab7065c45d4d"}, + {file = "duckdb-1.0.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3207936da9967ddbb60644ec291eb934d5819b08169bc35d08b2dedbe7068c60"}, + {file = "duckdb-1.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1128d6c9c33e883b1f5df6b57c1eb46b7ab1baf2650912d77ee769aaa05111f9"}, + {file = "duckdb-1.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:02310d263474d0ac238646677feff47190ffb82544c018b2ff732a4cb462c6ef"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:75586791ab2702719c284157b65ecefe12d0cca9041da474391896ddd9aa71a4"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_universal2.whl", hash = "sha256:83bb415fc7994e641344f3489e40430ce083b78963cb1057bf714ac3a58da3ba"}, + {file = "duckdb-1.0.0-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:bee2e0b415074e84c5a2cefd91f6b5ebeb4283e7196ba4ef65175a7cef298b57"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa5a4110d2a499312609544ad0be61e85a5cdad90e5b6d75ad16b300bf075b90"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa389e6a382d4707b5f3d1bc2087895925ebb92b77e9fe3bfb23c9b98372fdc"}, + {file = "duckdb-1.0.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ede6f5277dd851f1a4586b0c78dc93f6c26da45e12b23ee0e88c76519cbdbe0"}, + {file = "duckdb-1.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0b88cdbc0d5c3e3d7545a341784dc6cafd90fc035f17b2f04bf1e870c68456e5"}, + {file = "duckdb-1.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd1693cdd15375156f7fff4745debc14e5c54928589f67b87fb8eace9880c370"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:c65a7fe8a8ce21b985356ee3ec0c3d3b3b2234e288e64b4cfb03356dbe6e5583"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_universal2.whl", hash = "sha256:e5a8eda554379b3a43b07bad00968acc14dd3e518c9fbe8f128b484cf95e3d16"}, + {file = "duckdb-1.0.0-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:a1b6acdd54c4a7b43bd7cb584975a1b2ff88ea1a31607a2b734b17960e7d3088"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a677bb1b6a8e7cab4a19874249d8144296e6e39dae38fce66a80f26d15e670df"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:752e9d412b0a2871bf615a2ede54be494c6dc289d076974eefbf3af28129c759"}, + {file = "duckdb-1.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3aadb99d098c5e32d00dc09421bc63a47134a6a0de9d7cd6abf21780b678663c"}, + {file = "duckdb-1.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:83b7091d4da3e9301c4f9378833f5ffe934fb1ad2b387b439ee067b2c10c8bb0"}, + {file = "duckdb-1.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:6a8058d0148b544694cb5ea331db44f6c2a00a7b03776cc4dd1470735c3d5ff7"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e40cb20e5ee19d44bc66ec99969af791702a049079dc5f248c33b1c56af055f4"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7bce1bc0de9af9f47328e24e6e7e39da30093179b1c031897c042dd94a59c8e"}, + {file = "duckdb-1.0.0-cp37-cp37m-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8355507f7a04bc0a3666958f4414a58e06141d603e91c0fa5a7c50e49867fb6d"}, + {file = "duckdb-1.0.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:39f1a46f5a45ad2886dc9b02ce5b484f437f90de66c327f86606d9ba4479d475"}, + {file = "duckdb-1.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d29ba477b27ae41676b62c8fae8d04ee7cbe458127a44f6049888231ca58fa"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:1bea713c1925918714328da76e79a1f7651b2b503511498ccf5e007a7e67d49e"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_universal2.whl", hash = "sha256:bfe67f3bcf181edbf6f918b8c963eb060e6aa26697d86590da4edc5707205450"}, + {file = "duckdb-1.0.0-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:dbc6093a75242f002be1d96a6ace3fdf1d002c813e67baff52112e899de9292f"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba1881a2b11c507cee18f8fd9ef10100be066fddaa2c20fba1f9a664245cd6d8"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:445d0bb35087c522705c724a75f9f1c13f1eb017305b694d2686218d653c8142"}, + {file = "duckdb-1.0.0-cp38-cp38-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:224553432e84432ffb9684f33206572477049b371ce68cc313a01e214f2fbdda"}, + {file = "duckdb-1.0.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d3914032e47c4e76636ad986d466b63fdea65e37be8a6dfc484ed3f462c4fde4"}, + {file = "duckdb-1.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:af9128a2eb7e1bb50cd2c2020d825fb2946fdad0a2558920cd5411d998999334"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:dd2659a5dbc0df0de68f617a605bf12fe4da85ba24f67c08730984a0892087e8"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_universal2.whl", hash = "sha256:ac5a4afb0bc20725e734e0b2c17e99a274de4801aff0d4e765d276b99dad6d90"}, + {file = "duckdb-1.0.0-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:2c5a53bee3668d6e84c0536164589d5127b23d298e4c443d83f55e4150fafe61"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b980713244d7708b25ee0a73de0c65f0e5521c47a0e907f5e1b933d79d972ef6"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21cbd4f9fe7b7a56eff96c3f4d6778770dd370469ca2212eddbae5dd63749db5"}, + {file = "duckdb-1.0.0-cp39-cp39-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ed228167c5d49888c5ef36f6f9cbf65011c2daf9dcb53ea8aa7a041ce567b3e4"}, + {file = "duckdb-1.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:46d8395fbcea7231fd5032a250b673cc99352fef349b718a23dea2c0dd2b8dec"}, + {file = "duckdb-1.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:6ad1fc1a4d57e7616944166a5f9417bdbca1ea65c490797e3786e3a42e162d8a"}, + {file = "duckdb-1.0.0.tar.gz", hash = "sha256:a2a059b77bc7d5b76ae9d88e267372deff19c291048d59450c431e166233d453"}, ] [[package]] @@ -2194,13 +2193,13 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" [[package]] name = "pydantic-settings" -version = "2.3.2" +version = "2.3.3" description = "Settings management using Pydantic" optional = false python-versions = ">=3.8" files = [ - {file = "pydantic_settings-2.3.2-py3-none-any.whl", hash = "sha256:ae06e44349e4c7bff8d57aff415dfd397ae75c217a098d54e9e6990ad7594ac7"}, - {file = "pydantic_settings-2.3.2.tar.gz", hash = "sha256:05d33003c74c2cd585de97b59eb17b6ed67181bc8a3ce594d74b5d24e4df7323"}, + {file = "pydantic_settings-2.3.3-py3-none-any.whl", hash = "sha256:e4ed62ad851670975ec11285141db888fd24947f9440bd4380d7d8788d4965de"}, + {file = "pydantic_settings-2.3.3.tar.gz", hash = "sha256:87fda838b64b5039b970cd47c3e8a1ee460ce136278ff672980af21516f6e6ce"}, ] [package.dependencies] @@ -3245,4 +3244,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "48a7355a7096e763b75315d0704bed8f4d8134a33553e62bc305a686b9e72803" +content-hash = "3c83d086a178cebd83473758459c4f026907268dbf8c9ce45bc4bfb1f340e9a5" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 1dd16933a..1c026b983 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -52,7 +52,7 @@ docstring-parser = "^0.15" python-jose = "^3.3.0" pandas = "2.2.0" multiprocess = "^0.70.14" -duckdb = "^0.10.2" +duckdb = "^1.0.0" python-socketio = "^5.11.0" python-docx = "^1.1.0" jq = { version = "^1.7.0", markers = "sys_platform != 'win32'" } From 8fef4b2d3a4f12ed134f9df4d1102095062996e1 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 11:30:20 -0300 Subject: [PATCH 03/13] chore: Update langflow-base and langflow package versions to 0.0.66 and 1.0.0a55 respectively --- poetry.lock | 2 +- pyproject.toml | 2 +- src/backend/base/pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4701d9fb2..f248ce18b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -4377,7 +4377,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.65" +version = "0.0.66" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" diff --git a/pyproject.toml b/pyproject.toml index 2d1ad64f9..3b660249d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a54" +version = "1.0.0a55" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index 1c026b983..03f3f70f1 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow-base" -version = "0.0.65" +version = "0.0.66" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From ea305b824c99bde0df2817f5513564f4d13d3653 Mon Sep 17 00:00:00 2001 From: anovazzi1 Date: Thu, 13 Jun 2024 12:01:02 -0300 Subject: [PATCH 04/13] chore: Update displayOutputPreview logic in ParameterComponent --- .../GenericNode/components/parameterComponent/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 28d6779e7..99b28b7bf 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -91,7 +91,8 @@ export default function ParameterComponent({ const displayOutputPreview = !!flowPool[data.id] && - flowPool[data.id][flowPool[data.id].length - 1]?.valid; + flowPool[data.id][flowPool[data.id].length - 1]?.valid && + flowPool[data.id][flowPool[data.id].length - 1]?.data?.logs[0]?.message; const unknownOutput = !!( flowPool[data.id] && From d2ae69135685f6180560cd89c101969f2657fe73 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Thu, 13 Jun 2024 08:01:38 -0700 Subject: [PATCH 05/13] chore: Update schema.py and service.py to handle file serialization and deserialization (#2159) Refactor the MessageModel class in schema.py to include methods for validating and serializing the 'files' field. This ensures that the 'files' field can be properly handled when it is a string or a list. In service.py, update the query in the MonitorService class to include the 'files' field when retrieving messages from the database. This ensures that the 'files' field is included in the query results. --- src/backend/base/langflow/services/monitor/schema.py | 10 +++++++++- src/backend/base/langflow/services/monitor/service.py | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/services/monitor/schema.py b/src/backend/base/langflow/services/monitor/schema.py index a409f8337..22ccb2bb4 100644 --- a/src/backend/base/langflow/services/monitor/schema.py +++ b/src/backend/base/langflow/services/monitor/schema.py @@ -91,9 +91,17 @@ class MessageModel(DefaultModel): files: list[str] = [] @field_validator("files", mode="before") + @classmethod def validate_files(cls, v): if isinstance(v, str): - return json.loads(v) + v = json.loads(v) + return v + + @field_serializer("files") + @classmethod + def serialize_files(cls, v): + if isinstance(v, list): + return json.dumps(v) return v @classmethod diff --git a/src/backend/base/langflow/services/monitor/service.py b/src/backend/base/langflow/services/monitor/service.py index 92c642e20..c7d898d11 100644 --- a/src/backend/base/langflow/services/monitor/service.py +++ b/src/backend/base/langflow/services/monitor/service.py @@ -140,7 +140,7 @@ class MonitorService(Service): order: Optional[str] = "DESC", limit: Optional[int] = None, ): - query = "SELECT index, flow_id, sender_name, sender, session_id, text, timestamp FROM messages" + query = "SELECT index, flow_id, sender_name, sender, session_id, text, files, timestamp FROM messages" conditions = [] if sender: conditions.append(f"sender = '{sender}'") From 6dbc2c76e4713467fd8c2d6d733bc2b3320ce692 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:05:45 -0300 Subject: [PATCH 06/13] Update projects --- .langchain.db-shm | Bin 32768 -> 0 bytes .langchain.db-wal | 0 .../Langflow Document QA.json | 2 +- .../Langflow Memory Conversation.json | 237 +++++++-- .../VectorStore-RAG-Flows.json | 477 ++++++++++++++---- src/backend/base/langflow/langflow-pre.db-shm | Bin 32768 -> 0 bytes src/backend/base/langflow/langflow-pre.db-wal | Bin 700428 -> 0 bytes 7 files changed, 557 insertions(+), 159 deletions(-) delete mode 100644 .langchain.db-shm delete mode 100644 .langchain.db-wal delete mode 100644 src/backend/base/langflow/langflow-pre.db-shm delete mode 100644 src/backend/base/langflow/langflow-pre.db-wal diff --git a/.langchain.db-shm b/.langchain.db-shm deleted file mode 100644 index fe9ac2845eca6fe6da8a63cd096d9cf9e24ece10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeIuAr62r3 Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" + "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" }, "input_value": { "advanced": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 17707debc..df360b08c 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -5,14 +5,23 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["str", "Text", "object"], + "baseClasses": [ + "str", + "Text", + "object" + ], "dataType": "MemoryComponent", "id": "MemoryComponent-iDkC0" }, "targetHandle": { "fieldName": "context", "id": "Prompt-19lCm", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" } }, @@ -30,14 +39,24 @@ "className": "", "data": { "sourceHandle": { - "baseClasses": ["Text", "object", "Record", "str"], + "baseClasses": [ + "Text", + "object", + "Record", + "str" + ], "dataType": "ChatInput", "id": "ChatInput-Z6G1Z" }, "targetHandle": { "fieldName": "user_message", "id": "Prompt-19lCm", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" } }, @@ -55,14 +74,22 @@ "className": "", "data": { "sourceHandle": { - "baseClasses": ["Text", "str", "object"], + "baseClasses": [ + "Text", + "str", + "object" + ], "dataType": "Prompt", "id": "Prompt-19lCm" }, "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-1v5Hz", - "inputTypes": ["Text", "Record", "Prompt"], + "inputTypes": [ + "Text", + "Record", + "Prompt" + ], "type": "str" } }, @@ -79,14 +106,20 @@ "className": "", "data": { "sourceHandle": { - "baseClasses": ["str", "object", "Text"], + "baseClasses": [ + "str", + "object", + "Text" + ], "dataType": "OpenAIModel", "id": "OpenAIModel-1v5Hz" }, "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-i56kN", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" } }, @@ -103,14 +136,21 @@ "className": "", "data": { "sourceHandle": { - "baseClasses": ["str", "Text", "object"], + "baseClasses": [ + "str", + "Text", + "object" + ], "dataType": "MemoryComponent", "id": "MemoryComponent-iDkC0" }, "targetHandle": { "fieldName": "input_value", "id": "TextOutput-KuLNK", - "inputTypes": ["Record", "Text"], + "inputTypes": [ + "Record", + "Text" + ], "type": "str" } }, @@ -129,7 +169,12 @@ "data": { "id": "ChatInput-Z6G1Z", "node": { - "base_classes": ["Text", "object", "Record", "str"], + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], "beta": false, "custom_fields": { "input_value": null, @@ -145,7 +190,10 @@ "field_order": [], "frozen": false, "icon": "ChatInput", - "output_types": ["Message", "Text"], + "output_types": [ + "Message", + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -164,7 +212,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" + "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" }, "input_value": { "advanced": false, @@ -193,12 +241,17 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "password": false, "placeholder": "", "required": false, @@ -214,7 +267,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -234,7 +289,9 @@ "fileTypes": [], "file_path": "", "info": "If provided, the message will be stored in the memory.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -270,7 +327,12 @@ "data": { "id": "ChatOutput-i56kN", "node": { - "base_classes": ["Text", "object", "Record", "str"], + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], "beta": false, "custom_fields": { "input_value": null, @@ -286,7 +348,10 @@ "field_order": [], "frozen": false, "icon": "ChatOutput", - "output_types": ["Message", "Text"], + "output_types": [ + "Message", + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -314,7 +379,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -333,12 +400,17 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "password": false, "placeholder": "", "required": false, @@ -354,7 +426,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -374,7 +448,9 @@ "fileTypes": [], "file_path": "", "info": "If provided, the message will be stored in the memory.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -412,7 +488,11 @@ "display_name": "Chat Memory", "id": "MemoryComponent-iDkC0", "node": { - "base_classes": ["str", "Text", "object"], + "base_classes": [ + "str", + "Text", + "object" + ], "beta": true, "custom_fields": { "n_messages": null, @@ -429,7 +509,9 @@ "field_order": [], "frozen": false, "icon": "history", - "output_types": ["Text"], + "output_types": [ + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -476,12 +558,17 @@ "fileTypes": [], "file_path": "", "info": "Order of the messages.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "order", - "options": ["Ascending", "Descending"], + "options": [ + "Ascending", + "Descending" + ], "password": false, "placeholder": "", "required": false, @@ -497,7 +584,9 @@ "fileTypes": [], "file_path": "", "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -517,12 +606,18 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "sender", - "options": ["Machine", "User", "Machine and User"], + "options": [ + "Machine", + "User", + "Machine and User" + ], "password": false, "placeholder": "", "required": false, @@ -538,7 +633,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -557,7 +654,9 @@ "fileTypes": [], "file_path": "", "info": "Session ID of the chat history.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -595,10 +694,17 @@ "display_name": "Prompt", "id": "Prompt-19lCm", "node": { - "base_classes": ["Text", "str", "object"], + "base_classes": [ + "Text", + "str", + "object" + ], "beta": false, "custom_fields": { - "template": ["context", "user_message"] + "template": [ + "context", + "user_message" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", @@ -613,7 +719,9 @@ "is_input": null, "is_output": null, "name": "", - "output_types": ["Prompt"], + "output_types": [ + "Prompt" + ], "template": { "_type": "CustomComponent", "code": { @@ -667,7 +775,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -729,7 +839,11 @@ "data": { "id": "OpenAIModel-1v5Hz", "node": { - "base_classes": ["str", "object", "Text"], + "base_classes": [ + "str", + "object", + "Text" + ], "beta": false, "custom_fields": { "input_value": null, @@ -759,7 +873,9 @@ ], "frozen": false, "icon": "OpenAI", - "output_types": ["Text"], + "output_types": [ + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -787,7 +903,11 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text", "Record", "Prompt"], + "input_types": [ + "Text", + "Record", + "Prompt" + ], "list": false, "load_from_db": false, "multiline": false, @@ -844,7 +964,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -871,7 +993,9 @@ "fileTypes": [], "file_path": "", "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -890,7 +1014,9 @@ "fileTypes": [], "file_path": "", "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -929,7 +1055,9 @@ "fileTypes": [], "file_path": "", "info": "System message to pass to the model.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -992,7 +1120,11 @@ "edited": false, "id": "TextOutput-KuLNK", "node": { - "base_classes": ["object", "str", "Text"], + "base_classes": [ + "object", + "str", + "Text" + ], "beta": false, "custom_fields": { "input_value": null, @@ -1006,7 +1138,9 @@ "field_order": [], "frozen": false, "icon": "type", - "output_types": ["Text"], + "output_types": [ + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -1034,7 +1168,10 @@ "fileTypes": [], "file_path": "", "info": "Text or Record to be passed as output.", - "input_types": ["Record", "Text"], + "input_types": [ + "Record", + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1054,7 +1191,9 @@ "fileTypes": [], "file_path": "", "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1100,4 +1239,4 @@ "is_component": false, "last_tested_version": "1.0.0a52", "name": "Memory Chatbot" -} +} \ No newline at end of file diff --git a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json index 6247f0c5d..c9745183d 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/VectorStore-RAG-Flows.json @@ -5,14 +5,23 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "TextOutput", "id": "TextOutput-BDknO" }, "targetHandle": { "fieldName": "context", "id": "Prompt-xeI6K", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" } }, @@ -30,14 +39,24 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Text", "str", "object", "Record"], + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], "dataType": "ChatInput", "id": "ChatInput-yxMKE" }, "targetHandle": { "fieldName": "question", "id": "Prompt-xeI6K", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" } }, @@ -55,14 +74,22 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "Prompt", "id": "Prompt-xeI6K" }, "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-EjXlN", - "inputTypes": ["Text", "Record", "Prompt"], + "inputTypes": [ + "Text", + "Record", + "Prompt" + ], "type": "str" } }, @@ -80,14 +107,20 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "OpenAIModel", "id": "OpenAIModel-EjXlN" }, "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-Q39I8", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" } }, @@ -105,14 +138,19 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "File", "id": "File-t0a6a" }, "targetHandle": { "fieldName": "inputs", "id": "RecursiveCharacterTextSplitter-tR9QM", - "inputTypes": ["Document", "Record"], + "inputTypes": [ + "Document", + "Record" + ], "type": "Document" } }, @@ -130,7 +168,9 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Embeddings"], + "baseClasses": [ + "Embeddings" + ], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-ZlOk1" }, @@ -154,14 +194,21 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Text", "str", "object", "Record"], + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], "dataType": "ChatInput", "id": "ChatInput-yxMKE" }, "targetHandle": { "fieldName": "input_value", "id": "AstraDBSearch-41nRz", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" } }, @@ -178,7 +225,9 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "RecursiveCharacterTextSplitter", "id": "RecursiveCharacterTextSplitter-tR9QM" }, @@ -203,7 +252,9 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Embeddings"], + "baseClasses": [ + "Embeddings" + ], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-9TPjc" }, @@ -228,14 +279,19 @@ "className": "stroke-gray-900 stroke-connection", "data": { "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "AstraDBSearch", "id": "AstraDBSearch-41nRz" }, "targetHandle": { "fieldName": "input_value", "id": "TextOutput-BDknO", - "inputTypes": ["Record", "Text"], + "inputTypes": [ + "Record", + "Text" + ], "type": "str" } }, @@ -254,7 +310,12 @@ "data": { "id": "ChatInput-yxMKE", "node": { - "base_classes": ["Text", "str", "object", "Record"], + "base_classes": [ + "Text", + "str", + "object", + "Record" + ], "beta": false, "custom_fields": { "input_value": null, @@ -270,7 +331,10 @@ "field_order": [], "frozen": false, "icon": "ChatInput", - "output_types": ["Message", "Text"], + "output_types": [ + "Message", + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -289,7 +353,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" + "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" }, "input_value": { "advanced": false, @@ -318,12 +382,17 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "password": false, "placeholder": "", "required": false, @@ -339,7 +408,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -359,7 +430,9 @@ "fileTypes": [], "file_path": "", "info": "If provided, the message will be stored in the memory.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -389,7 +462,11 @@ "data": { "id": "TextOutput-BDknO", "node": { - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "beta": false, "custom_fields": { "input_value": null, @@ -402,7 +479,9 @@ "field_order": [], "frozen": false, "icon": "type", - "output_types": ["Text"], + "output_types": [ + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -430,7 +509,10 @@ "fileTypes": [], "file_path": "", "info": "Text or Record to be passed as output.", - "input_types": ["Record", "Text"], + "input_types": [ + "Record", + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -450,7 +532,9 @@ "fileTypes": [], "file_path": "", "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -486,7 +570,9 @@ "data": { "id": "OpenAIEmbeddings-ZlOk1", "node": { - "base_classes": ["Embeddings"], + "base_classes": [ + "Embeddings" + ], "beta": false, "custom_fields": { "allowed_special": null, @@ -518,7 +604,9 @@ "field_formatters": {}, "field_order": [], "frozen": false, - "output_types": ["Embeddings"], + "output_types": [ + "Embeddings" + ], "template": { "_type": "CustomComponent", "allowed_special": { @@ -528,7 +616,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -576,7 +666,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, NestedDict\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n" + "value": "from typing import Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, NestedDict\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n \"dimensions\": {\n \"display_name\": \"Dimensions\",\n \"info\": \"The number of dimensions the resulting output embeddings should have. Only supported by certain models.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n dimensions: Optional[int] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n dimensions=dimensions,\n )\n" }, "default_headers": { "advanced": true, @@ -622,7 +712,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -642,7 +734,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -653,7 +747,9 @@ "show": true, "title_case": false, "type": "str", - "value": ["all"] + "value": [ + "all" + ] }, "embedding_ctx_length": { "advanced": true, @@ -700,7 +796,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -744,7 +842,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -763,7 +863,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -783,7 +885,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -802,7 +906,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -821,7 +927,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -840,7 +948,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -940,7 +1050,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -971,7 +1083,11 @@ "data": { "id": "OpenAIModel-EjXlN", "node": { - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "beta": false, "custom_fields": { "input_value": null, @@ -1001,7 +1117,9 @@ ], "frozen": false, "icon": "OpenAI", - "output_types": ["Text"], + "output_types": [ + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -1029,7 +1147,11 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text", "Record", "Prompt"], + "input_types": [ + "Text", + "Record", + "Prompt" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1086,7 +1208,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -1113,7 +1237,9 @@ "fileTypes": [], "file_path": "", "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1132,7 +1258,9 @@ "fileTypes": [], "file_path": "", "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -1171,7 +1299,9 @@ "fileTypes": [], "file_path": "", "info": "System message to pass to the model.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1233,10 +1363,17 @@ "display_name": "Prompt", "id": "Prompt-xeI6K", "node": { - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "beta": false, "custom_fields": { - "template": ["context", "question"] + "template": [ + "context", + "question" + ] }, "description": "Create a prompt template with dynamic variables.", "display_name": "Prompt", @@ -1251,7 +1388,9 @@ "is_input": null, "is_output": null, "name": "", - "output_types": ["Prompt"], + "output_types": [ + "Prompt" + ], "template": { "_type": "CustomComponent", "code": { @@ -1331,7 +1470,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1367,7 +1508,12 @@ "data": { "id": "ChatOutput-Q39I8", "node": { - "base_classes": ["object", "Text", "Record", "str"], + "base_classes": [ + "object", + "Text", + "Record", + "str" + ], "beta": false, "custom_fields": { "input_value": null, @@ -1384,7 +1530,10 @@ "field_order": [], "frozen": false, "icon": "ChatOutput", - "output_types": ["Message", "Text"], + "output_types": [ + "Message", + "Text" + ], "template": { "_type": "CustomComponent", "code": { @@ -1412,7 +1561,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": true, @@ -1431,12 +1582,17 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "sender", - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "password": false, "placeholder": "", "required": false, @@ -1452,7 +1608,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1472,7 +1630,9 @@ "fileTypes": [], "file_path": "", "info": "If provided, the message will be stored in the memory.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1507,7 +1667,9 @@ "data": { "id": "File-t0a6a", "node": { - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "beta": false, "custom_fields": { "path": null, @@ -1520,7 +1682,9 @@ "field_order": [], "frozen": false, "icon": "file-text", - "output_types": ["Record"], + "output_types": [ + "Record" + ], "template": { "_type": "CustomComponent", "code": { @@ -1621,7 +1785,9 @@ "data": { "id": "RecursiveCharacterTextSplitter-tR9QM", "node": { - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "beta": false, "custom_fields": { "chunk_overlap": null, @@ -1635,7 +1801,9 @@ "field_formatters": {}, "field_order": [], "frozen": false, - "output_types": ["Record"], + "output_types": [ + "Record" + ], "template": { "_type": "CustomComponent", "chunk_overlap": { @@ -1701,7 +1869,10 @@ "fileTypes": [], "file_path": "", "info": "The texts to split.", - "input_types": ["Document", "Record"], + "input_types": [ + "Document", + "Record" + ], "list": true, "load_from_db": false, "multiline": false, @@ -1720,7 +1891,9 @@ "fileTypes": [], "file_path": "", "info": "The characters to split on.\nIf left empty defaults to [\"\\n\\n\", \"\\n\", \" \", \"\"].", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -1731,7 +1904,9 @@ "show": true, "title_case": false, "type": "str", - "value": [""] + "value": [ + "" + ] } } }, @@ -1756,7 +1931,9 @@ "data": { "id": "AstraDBSearch-41nRz", "node": { - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "beta": false, "custom_fields": { "api_endpoint": null, @@ -1791,7 +1968,9 @@ ], "frozen": false, "icon": "AstraDB", - "output_types": ["Record"], + "output_types": [ + "Record" + ], "template": { "_type": "CustomComponent", "api_endpoint": { @@ -1801,7 +1980,9 @@ "fileTypes": [], "file_path": "", "info": "API endpoint URL for the Astra DB service.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -1929,7 +2110,9 @@ "fileTypes": [], "file_path": "", "info": "The name of the collection within Astra DB where the vectors will be stored.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1967,7 +2150,9 @@ "fileTypes": [], "file_path": "", "info": "Input value to search", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -1986,7 +2171,9 @@ "fileTypes": [], "file_path": "", "info": "Optional list of metadata fields to exclude from the indexing.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -2005,7 +2192,9 @@ "fileTypes": [], "file_path": "", "info": "Optional list of metadata fields to include in the indexing.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -2024,7 +2213,9 @@ "fileTypes": [], "file_path": "", "info": "Optional distance metric for vector comparisons in the vector store.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2043,7 +2234,9 @@ "fileTypes": [], "file_path": "", "info": "Optional namespace within Astra DB to use for the collection.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2100,12 +2293,17 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "search_type", - "options": ["Similarity", "MMR"], + "options": [ + "Similarity", + "MMR" + ], "password": false, "placeholder": "", "required": false, @@ -2121,12 +2319,18 @@ "fileTypes": [], "file_path": "", "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "setup_mode", - "options": ["Sync", "Async", "Off"], + "options": [ + "Sync", + "Async", + "Off" + ], "password": false, "placeholder": "", "required": false, @@ -2142,7 +2346,9 @@ "fileTypes": [], "file_path": "", "info": "Authentication token for accessing Astra DB.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -2178,7 +2384,9 @@ "data": { "id": "AstraDB-eUCSS", "node": { - "base_classes": ["VectorStore"], + "base_classes": [ + "VectorStore" + ], "beta": false, "custom_fields": { "api_endpoint": null, @@ -2211,7 +2419,10 @@ ], "frozen": false, "icon": "AstraDB", - "output_types": ["VectorStore", "BaseRetriever"], + "output_types": [ + "VectorStore", + "BaseRetriever" + ], "template": { "_type": "CustomComponent", "api_endpoint": { @@ -2221,7 +2432,9 @@ "fileTypes": [], "file_path": "", "info": "API endpoint URL for the Astra DB service.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -2349,7 +2562,9 @@ "fileTypes": [], "file_path": "", "info": "The name of the collection within Astra DB where the vectors will be stored.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2405,7 +2620,9 @@ "fileTypes": [], "file_path": "", "info": "Optional list of metadata fields to exclude from the indexing.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -2424,7 +2641,9 @@ "fileTypes": [], "file_path": "", "info": "Optional list of metadata fields to include in the indexing.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -2443,7 +2662,9 @@ "fileTypes": [], "file_path": "", "info": "Optional distance metric for vector comparisons in the vector store.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2462,7 +2683,9 @@ "fileTypes": [], "file_path": "", "info": "Optional namespace within Astra DB to use for the collection.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2500,12 +2723,18 @@ "fileTypes": [], "file_path": "", "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, "name": "setup_mode", - "options": ["Sync", "Async", "Off"], + "options": [ + "Sync", + "Async", + "Off" + ], "password": false, "placeholder": "", "required": false, @@ -2521,7 +2750,9 @@ "fileTypes": [], "file_path": "", "info": "Authentication token for accessing Astra DB.", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -2557,7 +2788,9 @@ "data": { "id": "OpenAIEmbeddings-9TPjc", "node": { - "base_classes": ["Embeddings"], + "base_classes": [ + "Embeddings" + ], "beta": false, "custom_fields": { "allowed_special": null, @@ -2589,7 +2822,9 @@ "field_formatters": {}, "field_order": [], "frozen": false, - "output_types": ["Embeddings"], + "output_types": [ + "Embeddings" + ], "template": { "_type": "CustomComponent", "allowed_special": { @@ -2599,7 +2834,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2647,7 +2884,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, NestedDict\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n )\n" + "value": "from typing import Dict, List, Optional\n\nfrom langchain_openai.embeddings.base import OpenAIEmbeddings\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, NestedDict\n\n\nclass OpenAIEmbeddingsComponent(CustomComponent):\n display_name = \"OpenAI Embeddings\"\n description = \"Generate embeddings using OpenAI models.\"\n\n def build_config(self):\n return {\n \"allowed_special\": {\n \"display_name\": \"Allowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"default_headers\": {\n \"display_name\": \"Default Headers\",\n \"advanced\": True,\n \"field_type\": \"dict\",\n },\n \"default_query\": {\n \"display_name\": \"Default Query\",\n \"advanced\": True,\n \"field_type\": \"NestedDict\",\n },\n \"disallowed_special\": {\n \"display_name\": \"Disallowed Special\",\n \"advanced\": True,\n \"field_type\": \"str\",\n \"is_list\": True,\n },\n \"chunk_size\": {\"display_name\": \"Chunk Size\", \"advanced\": True},\n \"client\": {\"display_name\": \"Client\", \"advanced\": True},\n \"deployment\": {\"display_name\": \"Deployment\", \"advanced\": True},\n \"embedding_ctx_length\": {\n \"display_name\": \"Embedding Context Length\",\n \"advanced\": True,\n },\n \"max_retries\": {\"display_name\": \"Max Retries\", \"advanced\": True},\n \"model\": {\n \"display_name\": \"Model\",\n \"advanced\": False,\n \"options\": [\n \"text-embedding-3-small\",\n \"text-embedding-3-large\",\n \"text-embedding-ada-002\",\n ],\n },\n \"model_kwargs\": {\"display_name\": \"Model Kwargs\", \"advanced\": True},\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"password\": True,\n \"advanced\": True,\n },\n \"openai_api_key\": {\"display_name\": \"OpenAI API Key\", \"password\": True},\n \"openai_api_type\": {\n \"display_name\": \"OpenAI API Type\",\n \"advanced\": True,\n \"password\": True,\n },\n \"openai_api_version\": {\n \"display_name\": \"OpenAI API Version\",\n \"advanced\": True,\n },\n \"openai_organization\": {\n \"display_name\": \"OpenAI Organization\",\n \"advanced\": True,\n },\n \"openai_proxy\": {\"display_name\": \"OpenAI Proxy\", \"advanced\": True},\n \"request_timeout\": {\"display_name\": \"Request Timeout\", \"advanced\": True},\n \"show_progress_bar\": {\n \"display_name\": \"Show Progress Bar\",\n \"advanced\": True,\n },\n \"skip_empty\": {\"display_name\": \"Skip Empty\", \"advanced\": True},\n \"tiktoken_model_name\": {\n \"display_name\": \"TikToken Model Name\",\n \"advanced\": True,\n },\n \"tiktoken_enable\": {\"display_name\": \"TikToken Enable\", \"advanced\": True},\n \"dimensions\": {\n \"display_name\": \"Dimensions\",\n \"info\": \"The number of dimensions the resulting output embeddings should have. Only supported by certain models.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n openai_api_key: str,\n default_headers: Optional[Dict[str, str]] = None,\n default_query: Optional[NestedDict] = {},\n allowed_special: List[str] = [],\n disallowed_special: List[str] = [\"all\"],\n chunk_size: int = 1000,\n deployment: str = \"text-embedding-ada-002\",\n embedding_ctx_length: int = 8191,\n max_retries: int = 6,\n model: str = \"text-embedding-ada-002\",\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n openai_api_type: Optional[str] = None,\n openai_api_version: Optional[str] = None,\n openai_organization: Optional[str] = None,\n openai_proxy: Optional[str] = None,\n request_timeout: Optional[float] = None,\n show_progress_bar: bool = False,\n skip_empty: bool = False,\n tiktoken_enable: bool = True,\n tiktoken_model_name: Optional[str] = None,\n dimensions: Optional[int] = None,\n ) -> Embeddings:\n # This is to avoid errors with Vector Stores (e.g Chroma)\n if disallowed_special == [\"all\"]:\n disallowed_special = \"all\" # type: ignore\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n return OpenAIEmbeddings(\n tiktoken_enabled=tiktoken_enable,\n default_headers=default_headers,\n default_query=default_query,\n allowed_special=set(allowed_special),\n disallowed_special=\"all\",\n chunk_size=chunk_size,\n deployment=deployment,\n embedding_ctx_length=embedding_ctx_length,\n max_retries=max_retries,\n model=model,\n model_kwargs=model_kwargs,\n base_url=openai_api_base,\n api_key=api_key,\n openai_api_type=openai_api_type,\n api_version=openai_api_version,\n organization=openai_organization,\n openai_proxy=openai_proxy,\n timeout=request_timeout,\n show_progress_bar=show_progress_bar,\n skip_empty=skip_empty,\n tiktoken_model_name=tiktoken_model_name,\n dimensions=dimensions,\n )\n" }, "default_headers": { "advanced": true, @@ -2693,7 +2930,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2713,7 +2952,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2724,7 +2965,9 @@ "show": true, "title_case": false, "type": "str", - "value": ["all"] + "value": [ + "all" + ] }, "embedding_ctx_length": { "advanced": true, @@ -2771,7 +3014,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": true, "load_from_db": false, "multiline": false, @@ -2815,7 +3060,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2834,7 +3081,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": true, "multiline": false, @@ -2854,7 +3103,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2873,7 +3124,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2892,7 +3145,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -2911,7 +3166,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -3011,7 +3268,9 @@ "fileTypes": [], "file_path": "", "info": "", - "input_types": ["Text"], + "input_types": [ + "Text" + ], "list": false, "load_from_db": false, "multiline": false, @@ -3054,4 +3313,4 @@ "is_component": false, "last_tested_version": "1.0.0a0", "name": "Vector Store RAG" -} +} \ No newline at end of file diff --git a/src/backend/base/langflow/langflow-pre.db-shm b/src/backend/base/langflow/langflow-pre.db-shm deleted file mode 100644 index e77ab53ece30e9457154ec69a6e96f32330d8acf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 32768 zcmeI5M^hA06oro<=7Mj57p91u){QW+uH1F%P z9#xmWJSdsdvij4qvX41cX%6#&+JS2U`SZ_Z{qUbZ*c+*&9qCCjNG2IT29qIVC>chw zNH!Txa>xjhOY%rQDIkSp6d6s%kO^cWDI$}|WHNYD zmXj4^C0Ru_kTP|8RJRFik)2l+*Qlk3Sq6}ds~ zlAk1_J}{1KBV}Ye*-3Vha#BG~lh5QkN#*a5t>VgQBtEn0&D3eQJ_G+Qbjg4W$bbyU zfDFih49I{C$bbyUfDFih49I{C$bbyUfDFih49I{C$bbyUfDFih49I{C$bbyUfDFih z49I{C$bbyUfDFih49I{C$bbyUfDFih49I{C$bbwqwEpkCiHBi0WfC*a%)k@ltb(yN zkc$h(Td0SH#@ToX22Qnb`)f1J?07C-I%+!5aT=!EUTUh7@0fyUNZ zTeXj_++^XjL7iE6Zje&Mxq;5u;e1g-u4rPNGUx8-**IfRa5kz9Qg$R0mG*<~f*9z6 zok8B(uL^P1en`l>rdaLz+{1C!^_qcmDvw5?svk?HW0%ob*Njp%p^>=cARRB!W?19; zR&#L9pynLBFi6>vfjDMA=q`wXt|$-kRqa^MhFV!)74YwTi8xtL>`lb6!Hiogvoh1`+ z$DKl+RH<)$mBf=)5jN?CeGyjpfB6{P`2R<~cuvJ8U(BH)Yy-Wq-+s`Y40vQ<0p57j z$;&oV@zBe59`xA)hjYd@rH(P{z zG3>6^&J46esj~$Mn@+(}gV`tHzCp_0ktFNurSULhdu)k^ZEBAW4D`VP2kAtPcEHvI z9e)}g`EK%gc*U9e;-K#)i_So4*cP3_zN^~6`T}_@#+r`Dv1l81&t&VH?O`uZpoM<{ DuY8%Z diff --git a/src/backend/base/langflow/langflow-pre.db-wal b/src/backend/base/langflow/langflow-pre.db-wal deleted file mode 100644 index 746a1fa81882d7af6763e805909d6861b4239a95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 700428 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 From 045cb38cd3400220c10610e0cc0052c40259b4c4 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:12:24 -0300 Subject: [PATCH 07/13] Update Memory Example --- .../Langflow Memory Conversation.json | 2316 ++++++++--------- 1 file changed, 1079 insertions(+), 1237 deletions(-) diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index df360b08c..55733f720 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -1,1242 +1,1084 @@ { - "data": { - "edges": [ - { - "className": "stroke-gray-900 stroke-connection", - "data": { - "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], - "dataType": "MemoryComponent", - "id": "MemoryComponent-iDkC0" - }, - "targetHandle": { - "fieldName": "context", - "id": "Prompt-19lCm", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-MemoryComponent-iDkC0{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-iDkC0œ}-Prompt-19lCm{œfieldNameœ:œcontextœ,œidœ:œPrompt-19lCmœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "MemoryComponent-iDkC0", - "sourceHandle": "{œbaseClassesœ: [œstrœ, œTextœ, œobjectœ], œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-iDkC0œ}", - "style": { - "stroke": "#555" - }, - "target": "Prompt-19lCm", - "targetHandle": "{œfieldNameœ: œcontextœ, œidœ: œPrompt-19lCmœ, œinputTypesœ: [œDocumentœ, œBaseOutputParserœ, œRecordœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "baseClasses": [ - "Text", - "object", - "Record", - "str" - ], - "dataType": "ChatInput", - "id": "ChatInput-Z6G1Z" - }, - "targetHandle": { - "fieldName": "user_message", - "id": "Prompt-19lCm", - "inputTypes": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-ChatInput-Z6G1Z{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z6G1Zœ}-Prompt-19lCm{œfieldNameœ:œuser_messageœ,œidœ:œPrompt-19lCmœ,œinputTypesœ:[œDocumentœ,œBaseOutputParserœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "selected": false, - "source": "ChatInput-Z6G1Z", - "sourceHandle": "{œbaseClassesœ: [œTextœ, œobjectœ, œRecordœ, œstrœ], œdataTypeœ: œChatInputœ, œidœ: œChatInput-Z6G1Zœ}", - "style": { - "stroke": "#555" - }, - "target": "Prompt-19lCm", - "targetHandle": "{œfieldNameœ: œuser_messageœ, œidœ: œPrompt-19lCmœ, œinputTypesœ: [œDocumentœ, œBaseOutputParserœ, œRecordœ, œTextœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "baseClasses": [ - "Text", - "str", - "object" - ], - "dataType": "Prompt", - "id": "Prompt-19lCm" - }, - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-1v5Hz", - "inputTypes": [ - "Text", - "Record", - "Prompt" - ], - "type": "str" - } - }, - "id": "reactflow__edge-Prompt-19lCm{œbaseClassesœ:[œTextœ,œstrœ,œobjectœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-19lCmœ}-OpenAIModel-1v5Hz{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-1v5Hzœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", - "source": "Prompt-19lCm", - "sourceHandle": "{œbaseClassesœ: [œTextœ, œstrœ, œobjectœ], œdataTypeœ: œPromptœ, œidœ: œPrompt-19lCmœ}", - "style": { - "stroke": "#555" - }, - "target": "OpenAIModel-1v5Hz", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-1v5Hzœ, œinputTypesœ: [œTextœ, œRecordœ, œPromptœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "baseClasses": [ - "str", - "object", - "Text" - ], - "dataType": "OpenAIModel", - "id": "OpenAIModel-1v5Hz" - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-i56kN", - "inputTypes": [ - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-1v5Hz{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-1v5Hzœ}-ChatOutput-i56kN{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-i56kNœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-1v5Hz", - "sourceHandle": "{œbaseClassesœ: [œstrœ, œobjectœ, œTextœ], œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-1v5Hzœ}", - "style": { - "stroke": "#555" - }, - "target": "ChatOutput-i56kN", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-i56kNœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}" - }, - { - "className": "", - "data": { - "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], - "dataType": "MemoryComponent", - "id": "MemoryComponent-iDkC0" - }, - "targetHandle": { - "fieldName": "input_value", - "id": "TextOutput-KuLNK", - "inputTypes": [ - "Record", - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-MemoryComponent-iDkC0{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-iDkC0œ}-TextOutput-KuLNK{œfieldNameœ:œinput_valueœ,œidœ:œTextOutput-KuLNKœ,œinputTypesœ:[œRecordœ,œTextœ],œtypeœ:œstrœ}", - "source": "MemoryComponent-iDkC0", - "sourceHandle": "{œbaseClassesœ: [œstrœ, œTextœ, œobjectœ], œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-iDkC0œ}", - "style": { - "stroke": "#555" - }, - "target": "TextOutput-KuLNK", - "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œTextOutput-KuLNKœ, œinputTypesœ: [œRecordœ, œTextœ], œtypeœ: œstrœ}" - } - ], - "nodes": [ - { - "data": { - "id": "ChatInput-Z6G1Z", - "node": { - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "return_record": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "ChatInput", - "output_types": [ - "Message", - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": false, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "If provided, the message will be stored in the memory.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 469, - "id": "ChatInput-Z6G1Z", - "position": { - "x": 1283.2700598313072, - "y": 982.5953650473145 - }, - "positionAbsolute": { - "x": 1283.2700598313072, - "y": 982.5953650473145 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "ChatOutput-i56kN", - "node": { - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "return_record": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "ChatOutput", - "output_types": [ - "Message", - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\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 files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": false, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "If provided, the message will be stored in the memory.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 477, - "id": "ChatOutput-i56kN", - "position": { - "x": 3154.916355514023, - "y": 851.051882666333 - }, - "positionAbsolute": { - "x": 3154.916355514023, - "y": 851.051882666333 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Retrieves stored chat messages given a specific Session ID.", - "display_name": "Chat Memory", - "id": "MemoryComponent-iDkC0", - "node": { - "base_classes": [ - "str", - "Text", - "object" - ], - "beta": true, - "custom_fields": { - "n_messages": null, - "order": null, - "record_template": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Retrieves stored chat messages given a specific Session ID.", - "display_name": "Chat Memory", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "history", - "output_types": [ - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.record import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n record_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=record_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n" - }, - "n_messages": { - "advanced": false, - "display_name": "Number of Messages", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Number of messages to retrieve.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "n_messages", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "int", - "value": 5 - }, - "order": { - "advanced": true, - "display_name": "Order", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Order of the messages.", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "order", - "options": [ - "Ascending", - "Descending" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Descending" - }, - "record_template": { - "advanced": true, - "display_name": "Record Template", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "record_template", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "{sender_name}: {text}" - }, - "sender": { - "advanced": false, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Machine and User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Session ID of the chat history.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "MemoryComponent" - }, - "dragging": false, - "height": 489, - "id": "MemoryComponent-iDkC0", - "position": { - "x": 1289.9606870058817, - "y": 442.16804561053766 - }, - "positionAbsolute": { - "x": 1289.9606870058817, - "y": 442.16804561053766 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "A component for creating prompt templates using dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-19lCm", - "node": { - "base_classes": [ - "Text", - "str", - "object" - ], - "beta": false, - "custom_fields": { - "template": [ - "context", - "user_message" - ] - }, - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "documentation": "", - "error": null, - "field_formatters": {}, - "field_order": [], - "frozen": false, - "full_path": null, - "icon": "prompts", - "is_composition": null, - "is_input": null, - "is_output": null, - "name": "", - "output_types": [ - "Prompt" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" - }, - "context": { - "advanced": false, - "display_name": "context", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "context", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "template", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "prompt", - "value": "{context}\n\nUser: {user_message}\nAI: " - }, - "user_message": { - "advanced": false, - "display_name": "user_message", - "dynamic": false, - "field_type": "str", - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Document", - "BaseOutputParser", - "Record", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "user_message", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } - } - }, - "type": "Prompt" - }, - "dragging": false, - "height": 477, - "id": "Prompt-19lCm", - "position": { - "x": 1894.594426342426, - "y": 753.3797365481901 - }, - "positionAbsolute": { - "x": 1894.594426342426, - "y": 753.3797365481901 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-1v5Hz", - "node": { - "base_classes": [ - "str", - "object", - "Text" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "max_tokens": null, - "model_kwargs": null, - "model_name": null, - "openai_api_base": null, - "openai_api_key": null, - "stream": null, - "system_message": null, - "temperature": null - }, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "field_formatters": {}, - "field_order": [ - "max_tokens", - "model_kwargs", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "input_value", - "system_message", - "stream" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [ - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text", - "Record", - "Prompt" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "input_value", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "str" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "max_tokens", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "int", - "value": 256 - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "model_kwargs", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "NestedDict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "gpt-3.5-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "openai_api_base", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": true, - "multiline": false, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "stream", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "System message to pass to the model.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "system_message", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "temperature", - "password": false, - "placeholder": "", - "rangeSpec": { - "max": 1, - "min": -1, - "step": 0.1, - "step_type": "float" + "id": "321b1bab-8691-42da-9689-1f12b5d2a48b", + "data": { + "nodes": [ + { + "data": { + "id": "ChatInput-Z9Rn6", + "node": { + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "return_record": null, + "sender": null, + "sender_name": null, + "session_id": null + }, + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "ChatInput", + "output_types": [ + "Message", + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "do you know his name?" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": false, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "If provided, the message will be stored in the memory.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } + } + }, + "type": "ChatInput" }, - "required": false, - "show": true, - "title_case": false, - "type": "float", - "value": "0.2" - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 563, - "id": "OpenAIModel-1v5Hz", - "position": { - "x": 2561.5850334731617, - "y": 553.2745131130916 - }, - "positionAbsolute": { - "x": 2561.5850334731617, - "y": 553.2745131130916 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Display a text output in the Playground.", - "display_name": "Inspect Memory", - "edited": false, - "id": "TextOutput-KuLNK", - "node": { - "base_classes": [ - "object", - "str", - "Text" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "record_template": null + "dragging": false, + "height": 477, + "id": "ChatInput-Z9Rn6", + "position": { + "x": 1283.2700598313072, + "y": 982.5953650473145 + }, + "positionAbsolute": { + "x": 1283.2700598313072, + "y": 982.5953650473145 + }, + "selected": false, + "type": "genericNode", + "width": 384 }, - "description": "Display a text output in the Playground.", - "display_name": "Inspect Memory", - "documentation": "", - "edited": true, - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "type", - "output_types": [ - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.io.text import TextComponent\nfrom langflow.field_typing import Text\n\n\nclass TextOutput(TextComponent):\n display_name = \"Text Output\"\n description = \"Display a text output in the Playground.\"\n icon = \"type\"\n\n def build_config(self):\n return {\n \"input_value\": {\n \"display_name\": \"Text\",\n \"input_types\": [\"Record\", \"Text\"],\n \"info\": \"Text or Record to be passed as output.\",\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def build(self, input_value: Optional[Text] = \"\", record_template: Optional[str] = \"\") -> Text:\n return super().build(input_value=input_value, record_template=record_template)\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Text or Record to be passed as output.", - "input_types": [ - "Record", - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "input_value", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - }, - "record_template": { - "advanced": true, - "display_name": "Record Template", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "record_template", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "" - } + { + "data": { + "id": "ChatOutput-cVR7W", + "node": { + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "return_record": null, + "sender": null, + "sender_name": null, + "session_id": null + }, + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "ChatOutput", + "output_types": [ + "Message", + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\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 files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": false, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "If provided, the message will be stored in the memory.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } + } + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 485, + "id": "ChatOutput-cVR7W", + "position": { + "x": 3154.916355514023, + "y": 851.051882666333 + }, + "positionAbsolute": { + "x": 3154.916355514023, + "y": 851.051882666333 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Retrieves stored chat messages given a specific Session ID.", + "display_name": "Chat Memory", + "id": "MemoryComponent-u6m5G", + "node": { + "base_classes": [ + "str", + "Text", + "object" + ], + "beta": true, + "custom_fields": { + "n_messages": null, + "order": null, + "record_template": null, + "sender": null, + "sender_name": null, + "session_id": null + }, + "description": "Retrieves stored chat messages given a specific Session ID.", + "display_name": "Chat Memory", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "history", + "output_types": [ + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.record import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n record_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=record_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n" + }, + "n_messages": { + "advanced": false, + "display_name": "Number of Messages", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Number of messages to retrieve.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "n_messages", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "int", + "value": 5 + }, + "order": { + "advanced": true, + "display_name": "Order", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Order of the messages.", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "order", + "options": [ + "Ascending", + "Descending" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Descending" + }, + "record_template": { + "advanced": true, + "display_name": "Record Template", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "record_template", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "{sender_name}: {text}" + }, + "sender": { + "advanced": false, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User", + "Machine and User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Machine and User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Session ID of the chat history.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } + } + }, + "type": "MemoryComponent" + }, + "dragging": false, + "height": 505, + "id": "MemoryComponent-u6m5G", + "position": { + "x": 1289.9606870058817, + "y": 442.16804561053766 + }, + "positionAbsolute": { + "x": 1289.9606870058817, + "y": 442.16804561053766 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-kykM2", + "node": { + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "template", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "prompt", + "value": "Previous messages:\n{Context}\n\nUser: {UserMessage}\nAI: " + }, + "Context": { + "field_type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "Context", + "display_name": "Context", + "advanced": false, + "input_types": [ + "Document", + "Message", + "Record", + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "type": "str" + }, + "UserMessage": { + "field_type": "str", + "required": false, + "placeholder": "", + "list": false, + "show": true, + "multiline": true, + "value": "", + "fileTypes": [], + "file_path": "", + "password": false, + "name": "UserMessage", + "display_name": "UserMessage", + "advanced": false, + "input_types": [ + "Document", + "Message", + "Record", + "Text" + ], + "dynamic": false, + "info": "", + "load_from_db": false, + "title_case": false, + "type": "str" + } + }, + "description": "Create a prompt template with dynamic variables.", + "icon": "prompts", + "is_input": null, + "is_output": null, + "is_composition": null, + "base_classes": [ + "object", + "str", + "Text" + ], + "name": "", + "display_name": "Prompt", + "documentation": "", + "custom_fields": { + "template": [ + "Context", + "UserMessage" + ] + }, + "output_types": [ + "Prompt" + ], + "full_path": null, + "field_formatters": {}, + "frozen": false, + "field_order": [], + "beta": false, + "error": null + }, + "type": "Prompt" + }, + "dragging": false, + "height": 513, + "id": "Prompt-kykM2", + "position": { + "x": 1890.2582485007167, + "y": 753.3797365481901 + }, + "positionAbsolute": { + "x": 1890.2582485007167, + "y": 753.3797365481901 + }, + "selected": true, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "OpenAIModel-Neuec", + "node": { + "base_classes": [ + "str", + "object", + "Text" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "max_tokens": null, + "model_kwargs": null, + "model_name": null, + "openai_api_base": null, + "openai_api_key": null, + "stream": null, + "system_message": null, + "temperature": null + }, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "field_formatters": {}, + "field_order": [ + "max_tokens", + "model_kwargs", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "input_value", + "system_message", + "stream" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [ + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text", + "Record", + "Prompt" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "input_value", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str" + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "max_tokens", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "int", + "value": 256 + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "model_kwargs", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "NestedDict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "gpt-3.5-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "openai_api_base", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": true, + "multiline": false, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "stream", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "System message to pass to the model.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "system_message", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "temperature", + "password": false, + "placeholder": "", + "rangeSpec": { + "max": 1, + "min": -1, + "step": 0.1, + "step_type": "float" + }, + "required": false, + "show": true, + "title_case": false, + "type": "float", + "value": "0.2" + } + } + }, + "type": "OpenAIModel" + }, + "dragging": false, + "height": 571, + "id": "OpenAIModel-Neuec", + "position": { + "x": 2561.5850334731617, + "y": 553.2745131130916 + }, + "positionAbsolute": { + "x": 2561.5850334731617, + "y": 553.2745131130916 + }, + "selected": false, + "type": "genericNode", + "width": 384 } - }, - "type": "TextOutput" - }, - "dragging": false, - "height": 289, - "id": "TextOutput-KuLNK", - "position": { - "x": 1911.4785906252087, - "y": 247.39079954376987 - }, - "positionAbsolute": { - "x": 1911.4785906252087, - "y": 247.39079954376987 - }, - "selected": false, - "type": "genericNode", - "width": 384 - } - ], - "viewport": { - "x": -569.862554459756, - "y": -42.08339711050985, - "zoom": 0.4868590524514978 - } - }, - "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", - "icon": "🀖", - "icon_bg_color": "#FFD700", - "id": "edee50d3-a7e7-4cc7-9448-cc662300e8fb", - "is_component": false, - "last_tested_version": "1.0.0a52", - "name": "Memory Chatbot" + ], + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "baseClasses": [ + "str", + "object", + "Text" + ], + "dataType": "OpenAIModel", + "id": "OpenAIModel-Neuec" + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-cVR7W", + "inputTypes": [ + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-Neuec{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}-ChatOutput-cVR7W{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-Neuec", + "sourceHandle": "{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}", + "style": { + "stroke": "#555" + }, + "target": "ChatOutput-cVR7W", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" + }, + { + "source": "Prompt-kykM2", + "sourceHandle": "{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}", + "target": "OpenAIModel-Neuec", + "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-Neuec", + "inputTypes": [ + "Text", + "Record", + "Prompt" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "object", + "str", + "Text" + ], + "dataType": "Prompt", + "id": "Prompt-kykM2" + } + }, + "id": "reactflow__edge-Prompt-kykM2{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}-OpenAIModel-Neuec{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", + "className": "" + }, + { + "source": "ChatInput-Z9Rn6", + "sourceHandle": "{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}", + "target": "Prompt-kykM2", + "targetHandle": "{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "UserMessage", + "id": "Prompt-kykM2", + "inputTypes": [ + "Document", + "Message", + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "Text", + "object", + "Record", + "str" + ], + "dataType": "ChatInput", + "id": "ChatInput-Z9Rn6" + } + }, + "id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" + }, + { + "source": "MemoryComponent-u6m5G", + "sourceHandle": "{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}", + "target": "Prompt-kykM2", + "targetHandle": "{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "data": { + "targetHandle": { + "fieldName": "Context", + "id": "Prompt-kykM2", + "inputTypes": [ + "Document", + "Message", + "Record", + "Text" + ], + "type": "str" + }, + "sourceHandle": { + "baseClasses": [ + "str", + "Text", + "object" + ], + "dataType": "MemoryComponent", + "id": "MemoryComponent-u6m5G" + } + }, + "id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" + } + ], + "viewport": { + "x": -511.79726701119625, + "y": 48.514712353620894, + "zoom": 0.4612356948928673 + } + }, + "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", + "name": "Memory Chatbot", + "last_tested_version": "1.0.0a54", + "is_component": false } \ No newline at end of file From 90798a91ea3c15a42c4fd8eb895e5673356101e6 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:13:27 -0300 Subject: [PATCH 08/13] Format code --- src/frontend/src/App.tsx | 6 +-- .../components/parameterComponent/index.tsx | 22 ++++---- .../tooltipRenderComponent/index.tsx | 2 +- .../src/CustomNodes/GenericNode/index.tsx | 30 +++++------ .../helpers/get-class-from-build-status.ts | 2 +- .../hooks/use-check-code-validity.tsx | 2 +- .../hooks/use-fetch-data-on-mount.tsx | 2 +- .../hooks/use-handle-new-value.tsx | 2 +- .../hooks/use-handle-node-class.tsx | 2 +- .../src/CustomNodes/hooks/use-icon-render.tsx | 4 +- .../CustomNodes/hooks/use-icons-status.tsx | 4 +- .../hooks/use-update-node-code.tsx | 4 +- .../src/CustomNodes/utils/get-field-title.tsx | 2 +- .../src/alerts/alertDropDown/index.tsx | 6 +-- .../src/components/ImageViewer/index.tsx | 14 ++--- .../folderAccordionComponent/index.tsx | 2 +- .../components/accordionComponent/index.tsx | 4 +- .../addNewVariableButton.tsx | 6 +-- .../components/dragCardComponent/index.tsx | 4 +- .../src/components/cardComponent/index.tsx | 18 +++---- .../components/cardsWrapComponent/index.tsx | 2 +- .../src/components/chatComponent/index.tsx | 8 +-- .../components/codeAreaComponent/index.tsx | 2 +- .../components/csvOutputComponent/index.tsx | 2 +- .../src/components/dictComponent/index.tsx | 2 +- .../components/dropdownComponent/index.tsx | 4 +- .../editFlowSettingsComponent/index.tsx | 2 +- .../components/genericIconComponent/index.tsx | 6 +-- .../components/menuBar/index.tsx | 4 +- .../src/components/headerComponent/index.tsx | 6 +-- .../horizontalScrollFadeComponent/index.tsx | 4 +- .../components/popover/index.tsx | 16 +++--- .../components/popoverObject/index.tsx | 24 ++++----- .../src/components/inputComponent/index.tsx | 12 ++--- .../components/inputFileComponent/index.tsx | 4 +- .../components/inputGlobalComponent/index.tsx | 8 +-- .../components/inputListComponent/index.tsx | 2 +- .../components/sideBarButtons/index.tsx | 2 +- .../components/sideBarFolderButtons/index.tsx | 18 +++---- .../hooks/use-on-file-drop.tsx | 10 ++-- .../components/TableOptions/index.tsx | 4 +- .../components/tableAutoCellRender/index.tsx | 2 +- .../components/tableNodeCellRender/index.tsx | 6 +-- .../src/components/tableComponent/index.tsx | 11 ++-- .../tagsSelectorComponent/index.tsx | 2 +- src/frontend/src/components/ui/accordion.tsx | 6 +-- src/frontend/src/components/ui/alert.tsx | 2 +- src/frontend/src/components/ui/badge.tsx | 2 +- src/frontend/src/components/ui/button.tsx | 6 +-- src/frontend/src/components/ui/card.tsx | 4 +- src/frontend/src/components/ui/checkbox.tsx | 4 +- .../src/components/ui/custom-accordion.tsx | 4 +- src/frontend/src/components/ui/form.tsx | 8 +-- .../src/components/ui/select-custom.tsx | 6 +-- src/frontend/src/components/ui/toggle.tsx | 2 +- src/frontend/src/components/ui/tooltip.tsx | 4 +- src/frontend/src/contexts/authContext.tsx | 6 +-- src/frontend/src/controllers/API/api.tsx | 10 ++-- .../API/helpers/check-duplicate-requests.ts | 2 +- src/frontend/src/controllers/API/index.ts | 52 +++++++++---------- src/frontend/src/icons/Groq/index.tsx | 2 +- src/frontend/src/icons/Streamlit/index.tsx | 2 +- src/frontend/src/index.tsx | 4 +- .../BundleModal/hooks/submit-folder.tsx | 4 +- .../components/csvSelect/index.tsx | 2 +- .../IOModal/components/IOFieldView/index.tsx | 4 +- .../components/SessionView/hooks/index.tsx | 2 +- .../IOModal/components/SessionView/index.tsx | 2 +- .../components/buttonSendWrapper/index.tsx | 4 +- .../components/textAreaWrapper/index.tsx | 6 +-- .../chatInput/hooks/use-drag-and-drop.tsx | 2 +- .../hooks/use-handle-file-change.tsx | 2 +- .../components/chatView/chatInput/index.tsx | 2 +- .../components/chatView/chatMessage/index.tsx | 16 +++--- .../chatView/fileComponent/index.tsx | 2 +- .../fileComponent/utils/handle-download.tsx | 4 +- .../utils/format-file-name.tsx | 2 +- .../IOModal/components/chatView/index.tsx | 6 +-- src/frontend/src/modals/IOModal/index.tsx | 40 +++++++------- src/frontend/src/modals/apiModal/index.tsx | 18 +++---- .../utils/check-can-build-tweak-object.ts | 2 +- .../apiModal/utils/get-changes-types.ts | 2 +- .../modals/apiModal/utils/get-curl-code.tsx | 6 +-- .../utils/get-nodes-with-default-value.ts | 4 +- .../apiModal/utils/get-python-api-code.tsx | 2 +- .../modals/apiModal/utils/get-python-code.tsx | 2 +- .../src/modals/apiModal/utils/get-value.ts | 2 +- .../modals/apiModal/utils/get-widget-code.tsx | 2 +- .../src/modals/apiModal/utils/tabs-array.tsx | 2 +- src/frontend/src/modals/baseModal/index.tsx | 14 ++--- .../src/modals/dictAreaModal/index.tsx | 2 +- .../editNodeModal/hooks/use-column-defs.tsx | 4 +- .../src/modals/editNodeModal/index.tsx | 9 ++-- src/frontend/src/modals/exportModal/index.tsx | 6 +-- .../src/modals/flowLogsModal/index.tsx | 4 +- .../foldersModal/hooks/submit-folder.tsx | 4 +- .../src/modals/genericModal/index.tsx | 6 +-- .../src/modals/newFlowModal/index.tsx | 2 +- src/frontend/src/modals/shareModal/index.tsx | 6 +-- .../modals/shareModal/utils/get-tags-ids.tsx | 2 +- .../components/PageComponent/index.tsx | 36 ++++++------- .../PageComponent/utils/get-random-name.tsx | 2 +- .../SelectionMenuComponent/index.tsx | 2 +- .../extraSidebarComponent/index.tsx | 28 +++++----- .../components/nodeToolbarComponent/index.tsx | 34 ++++++------ .../toolbarSelectItem/index.tsx | 2 +- src/frontend/src/pages/FlowPage/index.tsx | 2 +- .../hooks/use-delete-multiple.tsx | 2 +- .../hooks/use-filtered-flows.tsx | 4 +- .../hooks/use-handle-duplicate.tsx | 8 +-- .../hooks/use-handle-export.tsx | 4 +- .../hooks/use-handle-select-all.tsx | 2 +- .../hooks/use-select-options-change.tsx | 4 +- .../hooks/use-selected-flows.tsx | 2 +- .../components/componentsComponent/index.tsx | 22 ++++---- .../components/headerComponent/index.tsx | 2 +- .../headerTabsSearchComponent/index.tsx | 2 +- .../components/inputSearchComponent/index.tsx | 2 +- .../pages/MainPage/pages/mainPage/index.tsx | 2 +- .../src/pages/MainPage/services/index.ts | 12 ++--- .../MainPage/utils/handle-download-folder.ts | 2 +- src/frontend/src/pages/Playground/index.tsx | 2 +- .../src/pages/ProfileSettingsPage/index.tsx | 4 +- src/frontend/src/pages/SettingsPage/index.tsx | 2 +- .../hooks/use-handle-delete-key.tsx | 2 +- .../SettingsPage/pages/ApiKeysPage/index.tsx | 4 +- .../components/PasswordForm/index.tsx | 2 +- .../hooks/use-preload-images.tsx | 10 ++-- .../profilePictureChooserComponent/index.tsx | 2 +- .../components/StoreApiKeyForm/index.tsx | 4 +- .../SettingsPage/pages/GeneralPage/index.tsx | 10 ++-- .../pages/GlobalVariablesPage/index.tsx | 6 +-- .../EditShortcutButton/index.tsx | 10 ++-- .../pages/ShortcutsPage/index.tsx | 2 +- .../pages/hooks/use-patch-profile-picture.tsx | 2 +- .../SettingsPage/pages/hooks/use-save-key.tsx | 4 +- .../hooks/use-remove-messages.tsx | 2 +- .../SettingsPage/pages/messagesPage/index.tsx | 4 +- src/frontend/src/pages/StorePage/index.tsx | 6 +-- src/frontend/src/routes.tsx | 10 ++-- src/frontend/src/stores/darkStore.ts | 2 +- src/frontend/src/stores/flowStore.ts | 50 +++++++++--------- src/frontend/src/stores/flowsManagerStore.ts | 28 +++++----- src/frontend/src/stores/foldersStore.tsx | 10 ++-- .../globalVariablesStore/globalVariables.ts | 2 +- src/frontend/src/stores/messagesStore.ts | 6 +-- src/frontend/src/types/components/index.ts | 8 +-- src/frontend/src/types/store/index.ts | 2 +- src/frontend/src/types/zustand/flow/index.ts | 14 ++--- .../src/types/zustand/flowsManager/index.ts | 8 +-- .../types/zustand/globalVariables/index.ts | 2 +- src/frontend/src/utils/buildUtils.ts | 18 +++---- src/frontend/src/utils/parameterUtils.ts | 4 +- src/frontend/src/utils/storeUtils.ts | 2 +- src/frontend/src/utils/utils.ts | 20 +++---- .../tests/end-to-end/chatInputOutput.spec.ts | 6 +-- .../end-to-end/chatInputOutputUser.spec.ts | 8 +-- .../tests/end-to-end/dragAndDrop.spec.ts | 4 +- .../end-to-end/dropdownComponent.spec.ts | 28 +++++----- .../end-to-end/fileUploadComponent.spec.ts | 4 +- .../tests/end-to-end/filterEdge.spec.ts | 28 +++++----- .../tests/end-to-end/floatComponent.spec.ts | 20 +++---- .../tests/end-to-end/flowSettings.spec.ts | 4 +- src/frontend/tests/end-to-end/folders.spec.ts | 4 +- .../tests/end-to-end/inputComponent.spec.ts | 28 +++++----- .../end-to-end/inputListComponent.spec.ts | 18 +++---- .../end-to-end/keyPairListComponent.spec.ts | 4 +- .../end-to-end/langflowShortcuts.spec.ts | 4 +- .../tests/end-to-end/nestedComponent.spec.ts | 42 +++++++-------- src/frontend/tests/end-to-end/store.spec.ts | 2 +- .../end-to-end/textAreaModalComponent.spec.ts | 2 +- .../tests/end-to-end/toggleComponent.spec.ts | 34 ++++++------ 172 files changed, 652 insertions(+), 656 deletions(-) diff --git a/src/frontend/src/App.tsx b/src/frontend/src/App.tsx index 04d48103b..849244999 100644 --- a/src/frontend/src/App.tsx +++ b/src/frontend/src/App.tsx @@ -29,10 +29,10 @@ export default function App() { useTrackLastVisitedPath(); const removeFromTempNotificationList = useAlertStore( - (state) => state.removeFromTempNotificationList, + (state) => state.removeFromTempNotificationList ); const tempNotificationList = useAlertStore( - (state) => state.tempNotificationList, + (state) => state.tempNotificationList ); const [fetchError, setFetchError] = useState(false); const isLoading = useFlowsManagerStore((state) => state.isLoading); @@ -50,7 +50,7 @@ export default function App() { const refreshVersion = useDarkStore((state) => state.refreshVersion); const refreshStars = useDarkStore((state) => state.refreshStars); const setGlobalVariables = useGlobalVariablesStore( - (state) => state.setGlobalVariables, + (state) => state.setGlobalVariables ); const checkHasStore = useStoreStore((state) => state.checkHasStore); const navigate = useNavigate(); diff --git a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx index 99b28b7bf..8b76fc243 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/parameterComponent/index.tsx @@ -1,5 +1,6 @@ import { cloneDeep } from "lodash"; import { ReactNode, useEffect, useRef, useState } from "react"; +import { useHotkeys } from "react-hotkeys-hook"; import { Handle, Position, useUpdateNodeInternals } from "reactflow"; import CodeAreaComponent from "../../../../components/codeAreaComponent"; import DictComponent from "../../../../components/dictComponent"; @@ -24,6 +25,7 @@ import { import { Case } from "../../../../shared/components/caseComponent"; import useFlowStore from "../../../../stores/flowStore"; import useFlowsManagerStore from "../../../../stores/flowsManagerStore"; +import { useShortcutsStore } from "../../../../stores/shortcuts"; import { useTypesStore } from "../../../../stores/typesStore"; import { APIClassType } from "../../../../types/api"; import { ParameterComponentType } from "../../../../types/components"; @@ -48,11 +50,9 @@ import useFetchDataOnMount from "../../../hooks/use-fetch-data-on-mount"; import useHandleOnNewValue from "../../../hooks/use-handle-new-value"; import useHandleNodeClass from "../../../hooks/use-handle-node-class"; import useHandleRefreshButtonPress from "../../../hooks/use-handle-refresh-buttons"; +import OutputModal from "../outputModal"; import TooltipRenderComponent from "../tooltipRenderComponent"; import { TEXT_FIELD_TYPES } from "./constants"; -import OutputModal from "../outputModal"; -import { useShortcutsStore } from "../../../../stores/shortcuts"; -import { useHotkeys } from "react-hotkeys-hook"; export default function ParameterComponent({ left, @@ -121,7 +121,7 @@ export default function ParameterComponent({ debouncedHandleUpdateValues, setNode, renderTooltips, - setIsLoading, + setIsLoading ); const { handleNodeClass: handleNodeClassHook } = useHandleNodeClass( @@ -130,7 +130,7 @@ export default function ParameterComponent({ takeSnapshot, setNode, updateNodeInternals, - renderTooltips, + renderTooltips ); const { handleRefreshButtonPress: handleRefreshButtonPressHook } = @@ -139,7 +139,7 @@ export default function ParameterComponent({ let disabled = edges.some( (edge) => - edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id), + edge.targetHandle === scapedJSONStringfy(proxy ? { ...id, proxy } : id) ) ?? false; const handleRefreshButtonPress = async (name, data) => { @@ -152,12 +152,12 @@ export default function ParameterComponent({ handleUpdateValues, setNode, renderTooltips, - setIsLoading, + setIsLoading ); const handleOnNewValue = async ( newValue: string | string[] | boolean | Object[], - skipSnapshot: boolean | undefined = false, + skipSnapshot: boolean | undefined = false ): Promise => { handleOnNewValueHook(newValue, skipSnapshot); }; @@ -239,7 +239,7 @@ export default function ParameterComponent({ className={classNames( left ? "my-12 -ml-0.5 " : " my-12 -mr-0.5 ", "h-3 w-3 rounded-full border-2 bg-background", - !showNode ? "mt-0" : "", + !showNode ? "mt-0" : "" )} style={{ borderColor: color ?? nodeColors.unknown, @@ -309,7 +309,7 @@ export default function ParameterComponent({ "h-5 w-5 rounded-md", displayOutputPreview && !unknownOutput ? " hover:bg-secondary-foreground/5 hover:text-medium-indigo" - : " cursor-not-allowed text-muted-foreground", + : " cursor-not-allowed text-muted-foreground" )} name={"ScanEye"} /> @@ -359,7 +359,7 @@ export default function ParameterComponent({ } className={classNames( left ? "-ml-0.5" : "-mr-0.5", - "h-3 w-3 rounded-full border-2 bg-background", + "h-3 w-3 rounded-full border-2 bg-background" )} style={{ borderColor: color ?? nodeColors.unknown }} onClick={() => setFilterEdge(groupedEdge.current)} diff --git a/src/frontend/src/CustomNodes/GenericNode/components/tooltipRenderComponent/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/tooltipRenderComponent/index.tsx index ed2760161..c76bc7293 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/tooltipRenderComponent/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/tooltipRenderComponent/index.tsx @@ -24,7 +24,7 @@ const TooltipRenderComponent = ({ item, index, left }) => { 0 ? "mt-2 flex items-center" : "mt-3 flex items-center", + index > 0 ? "mt-2 flex items-center" : "mt-3 flex items-center" )} >
    state.setErrorData); const isDark = useDarkStore((state) => state.dark); const buildStatus = useFlowStore( - (state) => state.flowBuildStatus[data.id]?.status, + (state) => state.flowBuildStatus[data.id]?.status ); const lastRunTime = useFlowStore( - (state) => state.flowBuildStatus[data.id]?.timestamp, + (state) => state.flowBuildStatus[data.id]?.timestamp ); const takeSnapshot = useFlowsManagerStore((state) => state.takeSnapshot); @@ -72,7 +72,7 @@ export default function GenericNode({ const [nodeName, setNodeName] = useState(data.node!.display_name); const [inputDescription, setInputDescription] = useState(false); const [nodeDescription, setNodeDescription] = useState( - data.node?.description!, + data.node?.description! ); const [isOutdated, setIsOutdated] = useState(false); const [validationStatus, setValidationStatus] = @@ -90,7 +90,7 @@ export default function GenericNode({ data.node!, setNode, setIsOutdated, - updateNodeInternals, + updateNodeInternals ); const name = nodeIconsLucide[data.type] ? data.type : types[data.type]; @@ -117,12 +117,12 @@ export default function GenericNode({ selected: boolean, showNode: boolean, buildStatus: BuildStatus | undefined, - validationStatus: VertexBuildTypeAPI | null, + validationStatus: VertexBuildTypeAPI | null ) => { const specificClassFromBuildStatus = getSpecificClassFromBuildStatus( buildStatus, validationStatus, - isDark, + isDark ); const baseBorderClass = getBaseBorderClass(selected); @@ -131,7 +131,7 @@ export default function GenericNode({ baseBorderClass, nodeSizeClass, "generic-node-div group/node", - specificClassFromBuildStatus, + specificClassFromBuildStatus ); return names; }; @@ -176,7 +176,7 @@ export default function GenericNode({ showNode, isEmoji, nodeIconFragment, - checkNodeIconFragment, + checkNodeIconFragment ); function countHandles(): void { @@ -309,7 +309,7 @@ export default function GenericNode({ selected, showNode, buildStatus, - validationStatus, + validationStatus )} > {data.node?.beta && showNode && ( @@ -457,7 +457,7 @@ export default function GenericNode({ } title={getFieldTitle( data.node?.template!, - templateField, + templateField )} info={data.node?.template[templateField].info} name={templateField} @@ -485,7 +485,7 @@ export default function GenericNode({ proxy={data.node?.template[templateField].proxy} showNode={showNode} /> - ), + ) )} { setInputDescription(true); @@ -713,13 +713,13 @@ export default function GenericNode({ } title={getFieldTitle( data.node?.template!, - templateField, + templateField )} info={data.node?.template[templateField].info} name={templateField} tooltipTitle={ data.node?.template[templateField].input_types?.join( - "\n", + "\n" ) ?? data.node?.template[templateField].type } required={data.node!.template[templateField].required} @@ -746,7 +746,7 @@ export default function GenericNode({
    {" "} diff --git a/src/frontend/src/CustomNodes/helpers/get-class-from-build-status.ts b/src/frontend/src/CustomNodes/helpers/get-class-from-build-status.ts index 710e91d15..cf251c40c 100644 --- a/src/frontend/src/CustomNodes/helpers/get-class-from-build-status.ts +++ b/src/frontend/src/CustomNodes/helpers/get-class-from-build-status.ts @@ -4,7 +4,7 @@ import { VertexBuildTypeAPI } from "../../types/api"; export const getSpecificClassFromBuildStatus = ( buildStatus: BuildStatus | undefined, validationStatus: VertexBuildTypeAPI | null, - isDark: boolean, + isDark: boolean ) => { let isInvalid = validationStatus && !validationStatus.valid; diff --git a/src/frontend/src/CustomNodes/hooks/use-check-code-validity.tsx b/src/frontend/src/CustomNodes/hooks/use-check-code-validity.tsx index ec4d586f6..3a49ef62f 100644 --- a/src/frontend/src/CustomNodes/hooks/use-check-code-validity.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-check-code-validity.tsx @@ -6,7 +6,7 @@ const useCheckCodeValidity = ( data: NodeDataType, templates: { [key: string]: any }, setIsOutdated: (value: boolean) => void, - types, + types ) => { useEffect(() => { // This one should run only once diff --git a/src/frontend/src/CustomNodes/hooks/use-fetch-data-on-mount.tsx b/src/frontend/src/CustomNodes/hooks/use-fetch-data-on-mount.tsx index f203a059a..d8545d72a 100644 --- a/src/frontend/src/CustomNodes/hooks/use-fetch-data-on-mount.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-fetch-data-on-mount.tsx @@ -13,7 +13,7 @@ const useFetchDataOnMount = ( handleUpdateValues, setNode, renderTooltips, - setIsLoading, + setIsLoading ) => { const setErrorData = useAlertStore((state) => state.setErrorData); diff --git a/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx b/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx index 7be08491c..b41491f97 100644 --- a/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-handle-new-value.tsx @@ -14,7 +14,7 @@ const useHandleOnNewValue = ( debouncedHandleUpdateValues, setNode, renderTooltips, - setIsLoading, + setIsLoading ) => { const setErrorData = useAlertStore((state) => state.setErrorData); diff --git a/src/frontend/src/CustomNodes/hooks/use-handle-node-class.tsx b/src/frontend/src/CustomNodes/hooks/use-handle-node-class.tsx index 412658d77..bdcf1f8cc 100644 --- a/src/frontend/src/CustomNodes/hooks/use-handle-node-class.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-handle-node-class.tsx @@ -6,7 +6,7 @@ const useHandleNodeClass = ( takeSnapshot, setNode, updateNodeInternals, - renderTooltips, + renderTooltips ) => { const handleNodeClass = (newNodeClass, code) => { if (!data.node) return; diff --git a/src/frontend/src/CustomNodes/hooks/use-icon-render.tsx b/src/frontend/src/CustomNodes/hooks/use-icon-render.tsx index 181b4f515..cc9e29c0e 100644 --- a/src/frontend/src/CustomNodes/hooks/use-icon-render.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-icon-render.tsx @@ -12,8 +12,8 @@ const useIconNodeRender = ( checkNodeIconFragment: ( iconColor: string, iconName: string, - iconClassName: string, - ) => JSX.Element, + iconClassName: string + ) => JSX.Element ) => { const iconNodeRender = useCallback(() => { const iconElement = data?.node?.icon; diff --git a/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx b/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx index 42e8b64b3..19c6112d5 100644 --- a/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-icons-status.tsx @@ -1,14 +1,12 @@ -import ForwardedIconComponent from "../../components/genericIconComponent"; import Checkmark from "../../components/ui/checkmark"; import Loading from "../../components/ui/loading"; import Xmark from "../../components/ui/xmark"; import { BuildStatus } from "../../constants/enums"; import { VertexBuildTypeAPI } from "../../types/api"; -import { cn } from "../../utils/utils"; const useIconStatus = ( buildStatus: BuildStatus | undefined, - validationStatus: VertexBuildTypeAPI | null, + validationStatus: VertexBuildTypeAPI | null ) => { const conditionSuccess = validationStatus && validationStatus.valid; const conditionError = diff --git a/src/frontend/src/CustomNodes/hooks/use-update-node-code.tsx b/src/frontend/src/CustomNodes/hooks/use-update-node-code.tsx index f1593597f..d919a4fa9 100644 --- a/src/frontend/src/CustomNodes/hooks/use-update-node-code.tsx +++ b/src/frontend/src/CustomNodes/hooks/use-update-node-code.tsx @@ -7,7 +7,7 @@ const useUpdateNodeCode = ( dataNode: APIClassType, // Define YourNodeType according to your data structure setNode: (id: string, callback: (oldNode) => any) => void, setIsOutdated: (value: boolean) => void, - updateNodeInternals: (id: string) => void, + updateNodeInternals: (id: string) => void ) => { const updateNodeCode = useCallback( (newNodeClass: APIClassType, code: string, name: string) => { @@ -30,7 +30,7 @@ const useUpdateNodeCode = ( updateNodeInternals(dataId); }, - [dataId, dataNode, setNode, setIsOutdated, updateNodeInternals], + [dataId, dataNode, setNode, setIsOutdated, updateNodeInternals] ); return updateNodeCode; diff --git a/src/frontend/src/CustomNodes/utils/get-field-title.tsx b/src/frontend/src/CustomNodes/utils/get-field-title.tsx index e448c4f01..a00829a90 100644 --- a/src/frontend/src/CustomNodes/utils/get-field-title.tsx +++ b/src/frontend/src/CustomNodes/utils/get-field-title.tsx @@ -2,7 +2,7 @@ import { APITemplateType } from "../../types/api"; export default function getFieldTitle( template: APITemplateType, - templateField: string, + templateField: string ): string { return template[templateField].display_name ? template[templateField].display_name! diff --git a/src/frontend/src/alerts/alertDropDown/index.tsx b/src/frontend/src/alerts/alertDropDown/index.tsx index 05f42922d..6eff32fe2 100644 --- a/src/frontend/src/alerts/alertDropDown/index.tsx +++ b/src/frontend/src/alerts/alertDropDown/index.tsx @@ -16,13 +16,13 @@ export default function AlertDropdown({ }: AlertDropdownType): JSX.Element { const notificationList = useAlertStore((state) => state.notificationList); const clearNotificationList = useAlertStore( - (state) => state.clearNotificationList, + (state) => state.clearNotificationList ); const removeFromNotificationList = useAlertStore( - (state) => state.removeFromNotificationList, + (state) => state.removeFromNotificationList ); const setNotificationCenter = useAlertStore( - (state) => state.setNotificationCenter, + (state) => state.setNotificationCenter ); const [open, setOpen] = useState(false); diff --git a/src/frontend/src/components/ImageViewer/index.tsx b/src/frontend/src/components/ImageViewer/index.tsx index 8433962a7..dc7f41ad7 100644 --- a/src/frontend/src/components/ImageViewer/index.tsx +++ b/src/frontend/src/components/ImageViewer/index.tsx @@ -31,14 +31,14 @@ export default function ImageViewer({ image }) { const fullPageButton = document.getElementById("full-page-button"); zoomInButton!.addEventListener("click", () => - viewer.viewport.zoomBy(1.2), + viewer.viewport.zoomBy(1.2) ); zoomOutButton!.addEventListener("click", () => - viewer.viewport.zoomBy(0.8), + viewer.viewport.zoomBy(0.8) ); homeButton!.addEventListener("click", () => viewer.viewport.goHome()); fullPageButton!.addEventListener("click", () => - viewer.setFullScreen(true), + viewer.setFullScreen(true) ); // Optionally, you can set additional viewer options here @@ -47,16 +47,16 @@ export default function ImageViewer({ image }) { return () => { viewer.destroy(); zoomInButton!.removeEventListener("click", () => - viewer.viewport.zoomBy(1.2), + viewer.viewport.zoomBy(1.2) ); zoomOutButton!.removeEventListener("click", () => - viewer.viewport.zoomBy(0.8), + viewer.viewport.zoomBy(0.8) ); homeButton!.removeEventListener("click", () => - viewer.viewport.goHome(), + viewer.viewport.goHome() ); fullPageButton!.removeEventListener("click", () => - viewer.setFullScreen(true), + viewer.setFullScreen(true) ); }; } diff --git a/src/frontend/src/components/accordionComponent/composite/folderAccordionComponent/index.tsx b/src/frontend/src/components/accordionComponent/composite/folderAccordionComponent/index.tsx index d4fb95b5c..212a03fa2 100644 --- a/src/frontend/src/components/accordionComponent/composite/folderAccordionComponent/index.tsx +++ b/src/frontend/src/components/accordionComponent/composite/folderAccordionComponent/index.tsx @@ -15,7 +15,7 @@ export default function FolderAccordionComponent({ options, }: AccordionComponentType): JSX.Element { const [value, setValue] = useState( - open.length === 0 ? "" : getOpenAccordion(), + open.length === 0 ? "" : getOpenAccordion() ); function getOpenAccordion(): string { diff --git a/src/frontend/src/components/accordionComponent/index.tsx b/src/frontend/src/components/accordionComponent/index.tsx index c9c21b8b2..43a0aef79 100644 --- a/src/frontend/src/components/accordionComponent/index.tsx +++ b/src/frontend/src/components/accordionComponent/index.tsx @@ -17,7 +17,7 @@ export default function AccordionComponent({ sideBar, }: AccordionComponentType): JSX.Element { const [value, setValue] = useState( - open.length === 0 ? "" : getOpenAccordion(), + open.length === 0 ? "" : getOpenAccordion() ); function getOpenAccordion(): string { @@ -52,7 +52,7 @@ export default function AccordionComponent({ disabled={disabled} className={cn( sideBar ? "w-full bg-muted px-[0.75rem] py-[0.5rem]" : "ml-3", - disabled ? "cursor-not-allowed" : "cursor-pointer", + disabled ? "cursor-not-allowed" : "cursor-pointer" )} > {trigger} diff --git a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx index ae23c34ac..d75bf625c 100644 --- a/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx +++ b/src/frontend/src/components/addNewVariableButtonComponent/addNewVariableButton.tsx @@ -29,19 +29,19 @@ export default function AddNewVariableButton({ const setErrorData = useAlertStore((state) => state.setErrorData); const componentFields = useTypesStore((state) => state.ComponentFields); const unavaliableFields = new Set( - Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)), + Object.keys(useGlobalVariablesStore((state) => state.unavaliableFields)) ); const availableFields = () => { const fields = Array.from(componentFields).filter( - (field) => !unavaliableFields.has(field), + (field) => !unavaliableFields.has(field) ); return sortByName(fields); }; const addGlobalVariable = useGlobalVariablesStore( - (state) => state.addGlobalVariable, + (state) => state.addGlobalVariable ); function handleSaveVariable() { diff --git a/src/frontend/src/components/cardComponent/components/dragCardComponent/index.tsx b/src/frontend/src/components/cardComponent/components/dragCardComponent/index.tsx index 28674f3bc..54dbf4846 100644 --- a/src/frontend/src/components/cardComponent/components/dragCardComponent/index.tsx +++ b/src/frontend/src/components/cardComponent/components/dragCardComponent/index.tsx @@ -10,7 +10,7 @@ export default function DragCardComponent({ data }: { data: storeComponent }) { draggable //TODO check color schema className={cn( - "group relative flex flex-col justify-between overflow-hidden transition-all hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#ffffff10]", + "group relative flex flex-col justify-between overflow-hidden transition-all hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#ffffff10]" )} >
    @@ -22,7 +22,7 @@ export default function DragCardComponent({ data }: { data: storeComponent }) { "visible flex-shrink-0", data.is_component ? "mx-0.5 h-6 w-6 text-component-icon" - : "h-7 w-7 flex-shrink-0 text-flow-icon", + : "h-7 w-7 flex-shrink-0 text-flow-icon" )} name={data.is_component ? "ToyBrick" : "Group"} /> diff --git a/src/frontend/src/components/cardComponent/index.tsx b/src/frontend/src/components/cardComponent/index.tsx index d169a598a..a364a2d45 100644 --- a/src/frontend/src/components/cardComponent/index.tsx +++ b/src/frontend/src/components/cardComponent/index.tsx @@ -60,11 +60,11 @@ export default function CollectionCardComponent({ const [loading, setLoading] = useState(false); const [loadingLike, setLoadingLike] = useState(false); const [liked_by_user, setLiked_by_user] = useState( - data?.liked_by_user ?? false, + data?.liked_by_user ?? false ); const [likes_count, setLikes_count] = useState(data?.liked_by_count ?? 0); const [downloads_count, setDownloads_count] = useState( - data?.downloads_count ?? 0, + data?.downloads_count ?? 0 ); const currentFlow = useFlowsManagerStore((state) => state.currentFlow); const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow); @@ -75,12 +75,12 @@ export default function CollectionCardComponent({ const [openPlayground, setOpenPlayground] = useState(false); const [openDelete, setOpenDelete] = useState(false); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const [loadingPlayground, setLoadingPlayground] = useState(false); const selectedFlowsComponentsCards = useFlowsManagerStore( - (state) => state.selectedFlowsComponentsCards, + (state) => state.selectedFlowsComponentsCards ); const name = data.is_component ? "Component" : "Flow"; @@ -220,7 +220,7 @@ export default function CollectionCardComponent({ "group relative flex h-[11rem] flex-col justify-between overflow-hidden hover:bg-muted/50 hover:shadow-md hover:dark:bg-[#5f5f5f0e]", disabled ? "pointer-events-none opacity-50" : "", onClick ? "cursor-pointer" : "", - isSelectedCard ? "border border-selected" : "", + isSelectedCard ? "border border-selected" : "" )} onClick={onClick} > @@ -233,7 +233,7 @@ export default function CollectionCardComponent({ "visible flex-shrink-0", data.is_component ? "mx-0.5 h-6 w-6 text-component-icon" - : "h-7 w-7 flex-shrink-0 text-flow-icon", + : "h-7 w-7 flex-shrink-0 text-flow-icon" )} name={data.is_component ? "ToyBrick" : "Group"} /> @@ -428,7 +428,7 @@ export default function CollectionCardComponent({ name="Trash2" className={cn( "h-5 w-5", - !authorized ? " text-ring" : "", + !authorized ? " text-ring" : "" )} /> @@ -463,7 +463,7 @@ export default function CollectionCardComponent({ liked_by_user ? "fill-destructive stroke-destructive" : "", - !authorized ? " text-ring" : "", + !authorized ? " text-ring" : "" )} /> @@ -501,7 +501,7 @@ export default function CollectionCardComponent({ } className={cn( loading ? "h-5 w-5 animate-spin" : "h-5 w-5", - !authorized ? " text-ring" : "", + !authorized ? " text-ring" : "" )} /> diff --git a/src/frontend/src/components/cardsWrapComponent/index.tsx b/src/frontend/src/components/cardsWrapComponent/index.tsx index c7ca01588..0de3f1a2f 100644 --- a/src/frontend/src/components/cardsWrapComponent/index.tsx +++ b/src/frontend/src/components/cardsWrapComponent/index.tsx @@ -65,7 +65,7 @@ export default function CardsWrapComponent({ "h-full w-full", isDragging ? "mb-36 flex flex-col items-center justify-center gap-4 text-2xl font-light" - : "", + : "" )} > {isDragging ? ( diff --git a/src/frontend/src/components/chatComponent/index.tsx b/src/frontend/src/components/chatComponent/index.tsx index fab9a88d7..3040f685c 100644 --- a/src/frontend/src/components/chatComponent/index.tsx +++ b/src/frontend/src/components/chatComponent/index.tsx @@ -65,7 +65,7 @@ export default function FlowToolbar(): JSX.Element { "relative inline-flex h-full w-full items-center justify-center gap-[4px] bg-muted px-5 py-3 text-sm font-semibold text-foreground transition-all duration-150 ease-in-out hover:bg-background hover:bg-hover ", !hasApiKey || !validApiKey || !hasStore ? " button-disable text-muted-foreground " - : "", + : "" )} > Share @@ -88,7 +88,7 @@ export default function FlowToolbar(): JSX.Element { hasStore, openShareModal, setOpenShareModal, - ], + ] ); return ( @@ -144,7 +144,7 @@ export default function FlowToolbar(): JSX.Element { >
    { if (disabled && myValue !== "") { diff --git a/src/frontend/src/components/csvOutputComponent/index.tsx b/src/frontend/src/components/csvOutputComponent/index.tsx index 0b9a9d76e..1d4e342de 100644 --- a/src/frontend/src/components/csvOutputComponent/index.tsx +++ b/src/frontend/src/components/csvOutputComponent/index.tsx @@ -67,7 +67,7 @@ function CsvOutputComponent({ if (file) { const { rowData: data, colDefs: columns } = convertCSVToData( file, - separator, + separator ); setRowData(data); setColDefs(columns); diff --git a/src/frontend/src/components/dictComponent/index.tsx b/src/frontend/src/components/dictComponent/index.tsx index 057ba599d..b0340bf1a 100644 --- a/src/frontend/src/components/dictComponent/index.tsx +++ b/src/frontend/src/components/dictComponent/index.tsx @@ -24,7 +24,7 @@ export default function DictComponent({
    1 && editNode ? "my-1" : "", - "flex w-full flex-col gap-3", + "flex w-full flex-col gap-3" )} > { diff --git a/src/frontend/src/components/dropdownComponent/index.tsx b/src/frontend/src/components/dropdownComponent/index.tsx index 4aa9dcf07..0fd981603 100644 --- a/src/frontend/src/components/dropdownComponent/index.tsx +++ b/src/frontend/src/components/dropdownComponent/index.tsx @@ -58,7 +58,7 @@ export default function Dropdown({ ? "dropdown-component-outline" : "dropdown-component-false-outline", "w-full justify-between font-normal", - editNode ? "input-edit-node" : "py-2", + editNode ? "input-edit-node" : "py-2" )} > @@ -106,7 +106,7 @@ export default function Dropdown({ name="Check" className={cn( "ml-auto h-4 w-4 text-primary", - value === option ? "opacity-100" : "opacity-0", + value === option ? "opacity-100" : "opacity-0" )} /> diff --git a/src/frontend/src/components/editFlowSettingsComponent/index.tsx b/src/frontend/src/components/editFlowSettingsComponent/index.tsx index 26bc138e3..3dd813965 100644 --- a/src/frontend/src/components/editFlowSettingsComponent/index.tsx +++ b/src/frontend/src/components/editFlowSettingsComponent/index.tsx @@ -99,7 +99,7 @@ export const EditFlowSettings: React.FC = ({ {description === "" ? "No description" : description} diff --git a/src/frontend/src/components/genericIconComponent/index.tsx b/src/frontend/src/components/genericIconComponent/index.tsx index 9f7c687a1..398ae6e7f 100644 --- a/src/frontend/src/components/genericIconComponent/index.tsx +++ b/src/frontend/src/components/genericIconComponent/index.tsx @@ -18,7 +18,7 @@ export const ForwardedIconComponent = memo( strokeWidth, id = "", }: IconComponentProps, - ref, + ref ) => { const [showFallback, setShowFallback] = useState(false); @@ -65,8 +65,8 @@ export const ForwardedIconComponent = memo( /> ); - }, - ), + } + ) ); export default ForwardedIconComponent; diff --git a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx index 4965d37a6..83511c769 100644 --- a/src/frontend/src/components/headerComponent/components/menuBar/index.tsx +++ b/src/frontend/src/components/headerComponent/components/menuBar/index.tsx @@ -115,7 +115,7 @@ export const MenuBar = ({}: {}): JSX.Element => { title: UPLOAD_ERROR_ALERT, list: [error], }); - }, + } ); }} > @@ -201,7 +201,7 @@ export const MenuBar = ({}: {}): JSX.Element => { name={isBuilding || saveLoading ? "Loader2" : "CheckCircle2"} className={cn( "h-4 w-4", - isBuilding || saveLoading ? "animate-spin" : "animate-wiggle", + isBuilding || saveLoading ? "animate-spin" : "animate-wiggle" )} /> {printByBuildStatus()} diff --git a/src/frontend/src/components/headerComponent/index.tsx b/src/frontend/src/components/headerComponent/index.tsx index ef6b8938d..9b87335be 100644 --- a/src/frontend/src/components/headerComponent/index.tsx +++ b/src/frontend/src/components/headerComponent/index.tsx @@ -59,7 +59,7 @@ export default function Header(): JSX.Element { const lastFlowVisitedIndex = routeHistory .reverse() .findIndex( - (path) => path.includes("/flow/") && path !== location.pathname, + (path) => path.includes("/flow/") && path !== location.pathname ); const lastFlowVisited = routeHistory[lastFlowVisitedIndex]; @@ -201,7 +201,7 @@ export default function Header(): JSX.Element { src={ `${BACKEND_URL.slice( 0, - BACKEND_URL.length - 1, + BACKEND_URL.length - 1 )}${BASE_URL_API}files/profile_pictures/${ userData?.profile_image ?? "Space/046-rocket.svg" }` ?? profileCircle @@ -219,7 +219,7 @@ export default function Header(): JSX.Element { src={ `${BACKEND_URL.slice( 0, - BACKEND_URL.length - 1, + BACKEND_URL.length - 1 )}${BASE_URL_API}files/profile_pictures/${ userData?.profile_image ?? "Space/046-rocket.svg" }` ?? profileCircle diff --git a/src/frontend/src/components/horizontalScrollFadeComponent/index.tsx b/src/frontend/src/components/horizontalScrollFadeComponent/index.tsx index e0bf48917..7e0c788a6 100644 --- a/src/frontend/src/components/horizontalScrollFadeComponent/index.tsx +++ b/src/frontend/src/components/horizontalScrollFadeComponent/index.tsx @@ -32,11 +32,11 @@ export default function HorizontalScrollFadeComponent({ fadeContainerRef.current.classList.toggle( "fade-left", - isScrollable && !atStart, + isScrollable && !atStart ); fadeContainerRef.current.classList.toggle( "fade-right", - isScrollable && !atEnd, + isScrollable && !atEnd ); }; diff --git a/src/frontend/src/components/inputComponent/components/popover/index.tsx b/src/frontend/src/components/inputComponent/components/popover/index.tsx index e93f69207..06be89d91 100644 --- a/src/frontend/src/components/inputComponent/components/popover/index.tsx +++ b/src/frontend/src/components/inputComponent/components/popover/index.tsx @@ -75,9 +75,9 @@ const CustomInputPopover = ({ (selectedOption !== "" || !onChange) && setSelectedOption ? selectedOption : (selectedOptions?.length !== 0 || !onChange) && - setSelectedOptions - ? selectedOptions?.join(", ") - : value + setSelectedOptions + ? selectedOptions?.join(", ") + : value } autoFocus={autoFocus} disabled={disabled} @@ -103,7 +103,7 @@ const CustomInputPopover = ({ (password && !(setSelectedOption || setSelectedOptions)) ? "pr-8" : "", - className!, + className! )} placeholder={password && editNode ? "Key" : placeholder} onChange={handleInputChange} @@ -141,15 +141,15 @@ const CustomInputPopover = ({ onSelect={(currentValue) => { setSelectedOption && setSelectedOption( - currentValue === selectedOption ? "" : currentValue, + currentValue === selectedOption ? "" : currentValue ); setSelectedOptions && setSelectedOptions( selectedOptions?.includes(currentValue) ? selectedOptions.filter( - (item) => item !== currentValue, + (item) => item !== currentValue ) - : [...selectedOptions, currentValue], + : [...selectedOptions, currentValue] ); !setSelectedOptions && setShowOptions(false); }} @@ -162,7 +162,7 @@ const CustomInputPopover = ({ selectedOption === option || selectedOptions?.includes(option) ? "opacity-100" - : "opacity-0", + : "opacity-0" )} >
    diff --git a/src/frontend/src/components/inputComponent/components/popoverObject/index.tsx b/src/frontend/src/components/inputComponent/components/popoverObject/index.tsx index e907ec239..d43022845 100644 --- a/src/frontend/src/components/inputComponent/components/popoverObject/index.tsx +++ b/src/frontend/src/components/inputComponent/components/popoverObject/index.tsx @@ -60,14 +60,14 @@ const CustomInputPopoverObject = ({ ? options.find((option) => option.id === selectedOption)?.name || "" : (selectedOptions?.length !== 0 || !onChange) && - setSelectedOptions - ? selectedOptions - .map( - (optionId) => - options.find((option) => option.id === optionId)?.name, - ) - .join(", ") - : value + setSelectedOptions + ? selectedOptions + .map( + (optionId) => + options.find((option) => option.id === optionId)?.name + ) + .join(", ") + : value } autoFocus={autoFocus} disabled={disabled} @@ -115,15 +115,15 @@ const CustomInputPopoverObject = ({ onSelect={(currentValue) => { setSelectedOption && setSelectedOption( - currentValue === selectedOption ? "" : currentValue, + currentValue === selectedOption ? "" : currentValue ); setSelectedOptions && setSelectedOptions( selectedOptions?.includes(currentValue) ? selectedOptions.filter( - (item) => item !== currentValue, + (item) => item !== currentValue ) - : [...selectedOptions, currentValue], + : [...selectedOptions, currentValue] ); !setSelectedOptions && setShowOptions(false); }} @@ -136,7 +136,7 @@ const CustomInputPopoverObject = ({ selectedOption === option.id || selectedOptions?.includes(option.id) ? "opacity-100" - : "opacity-0", + : "opacity-0" )} >
    diff --git a/src/frontend/src/components/inputComponent/index.tsx b/src/frontend/src/components/inputComponent/index.tsx index c4a2453e2..c9f9a4170 100644 --- a/src/frontend/src/components/inputComponent/index.tsx +++ b/src/frontend/src/components/inputComponent/index.tsx @@ -72,7 +72,7 @@ export default function InputComponent({ editNode ? " input-edit-node " : "", password && editNode ? "pr-8" : "", password && !editNode ? "pr-10" : "", - className!, + className! )} placeholder={password && editNode ? "Key" : placeholder} onChange={(e) => { @@ -155,7 +155,7 @@ export default function InputComponent({ @@ -85,7 +85,7 @@ export default function TableOptions({ name="Trash2" className={cn( "h-5 w-5 text-primary transition-all", - !hasSelection ? "" : "hover:text-status-red ", + !hasSelection ? "" : "hover:text-status-red " )} /> diff --git a/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx index 903068c84..dd886e4fa 100644 --- a/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableAutoCellRender/index.tsx @@ -30,7 +30,7 @@ export default function TableAutoCellRender({ variant="outline" size="sq" className={cn( - "min-w-min bg-success-background text-success-foreground hover:bg-success-background", + "min-w-min bg-success-background text-success-foreground hover:bg-success-background" )} > {value} diff --git a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx index fb24786f7..925848d82 100644 --- a/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx +++ b/src/frontend/src/components/tableComponent/components/tableNodeCellRender/index.tsx @@ -72,8 +72,8 @@ export default function TableNodeCellRender({ ...id, proxy: templateData.proxy, } - : id, - ), + : id + ) ) ?? false; function getCellType() { switch (templateData.type) { @@ -144,7 +144,7 @@ export default function TableNodeCellRender({
    1 ? "my-3" : "", + templateValue?.length > 1 ? "my-3" : "" )} > ; @@ -36,7 +35,7 @@ const TableComponent = forwardRef< alertDescription = DEFAULT_TABLE_ALERT_MSG, ...props }, - ref, + ref ) => { let colDef = props.columnDefs.map((col, index) => { let newCol = { @@ -112,7 +111,7 @@ const TableComponent = forwardRef< }; const onColumnMoved = (params) => { const updatedColumnDefs = makeLastColumnNonResizable( - params.columnApi.getAllGridColumns().map((col) => col.getColDef()), + params.columnApi.getAllGridColumns().map((col) => col.getColDef()) ); params.api.setGridOption("columnDefs", updatedColumnDefs); if (props.onColumnMoved) props.onColumnMoved(params); @@ -136,7 +135,7 @@ const TableComponent = forwardRef< className={cn( dark ? "ag-theme-quartz-dark" : "ag-theme-quartz", "ag-theme-shadcn flex h-full flex-col", - "relative", + "relative" )} // applying the grid theme > source.includes("column"))) { localStorage.setItem( storeReference, - JSON.stringify(realRef.current?.api?.getColumnState()), + JSON.stringify(realRef.current?.api?.getColumnState()) ); setColumnStateChange(true); } @@ -176,7 +175,7 @@ const TableComponent = forwardRef< )}
    ); - }, + } ); export default TableComponent; diff --git a/src/frontend/src/components/tagsSelectorComponent/index.tsx b/src/frontend/src/components/tagsSelectorComponent/index.tsx index 4e3e181fc..6f84ae7c3 100644 --- a/src/frontend/src/components/tagsSelectorComponent/index.tsx +++ b/src/frontend/src/components/tagsSelectorComponent/index.tsx @@ -48,7 +48,7 @@ export function TagsSelector({ className={cn( selectedTags.some((category) => category === tag.name) ? "min-w-min bg-beta-foreground text-background hover:bg-beta-foreground" - : "", + : "" )} > {tag.name} diff --git a/src/frontend/src/components/ui/accordion.tsx b/src/frontend/src/components/ui/accordion.tsx index 39578095b..403b07996 100644 --- a/src/frontend/src/components/ui/accordion.tsx +++ b/src/frontend/src/components/ui/accordion.tsx @@ -34,7 +34,7 @@ const AccordionTrigger = React.forwardRef<
    svg]:rotate-180", - className, + className )} > {children} @@ -46,7 +46,7 @@ const AccordionTrigger = React.forwardRef< @@ -64,7 +64,7 @@ const AccordionContent = React.forwardRef< ref={ref} className={cn( "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden text-sm", - className, + className )} {...props} > diff --git a/src/frontend/src/components/ui/alert.tsx b/src/frontend/src/components/ui/alert.tsx index 05c5b7fa7..a584cea26 100644 --- a/src/frontend/src/components/ui/alert.tsx +++ b/src/frontend/src/components/ui/alert.tsx @@ -15,7 +15,7 @@ const alertVariants = cva( defaultVariants: { variant: "default", }, - }, + } ); const Alert = React.forwardRef< diff --git a/src/frontend/src/components/ui/badge.tsx b/src/frontend/src/components/ui/badge.tsx index 6eea7971a..8f8d1f6aa 100644 --- a/src/frontend/src/components/ui/badge.tsx +++ b/src/frontend/src/components/ui/badge.tsx @@ -27,7 +27,7 @@ const badgeVariants = cva( defaultVariants: { variant: "default", }, - }, + } ); export interface BadgeProps diff --git a/src/frontend/src/components/ui/button.tsx b/src/frontend/src/components/ui/button.tsx index ec3265bea..76f2316a0 100644 --- a/src/frontend/src/components/ui/button.tsx +++ b/src/frontend/src/components/ui/button.tsx @@ -35,7 +35,7 @@ const buttonVariants = cva( variant: "default", size: "default", }, - }, + } ); export interface ButtonProps @@ -65,7 +65,7 @@ const Button = React.forwardRef( children, ...props }, - ref, + ref ) => { const Comp = asChild ? Slot : "button"; let newChildren = children; @@ -97,7 +97,7 @@ const Button = React.forwardRef( ); - }, + } ); Button.displayName = "Button"; diff --git a/src/frontend/src/components/ui/card.tsx b/src/frontend/src/components/ui/card.tsx index a558fb645..d986c5530 100644 --- a/src/frontend/src/components/ui/card.tsx +++ b/src/frontend/src/components/ui/card.tsx @@ -9,7 +9,7 @@ const Card = React.forwardRef< ref={ref} className={cn( "flex flex-col justify-between rounded-lg border bg-muted text-card-foreground shadow-sm transition-all", - className, + className )} {...props} /> @@ -36,7 +36,7 @@ const CardTitle = React.forwardRef< ref={ref} className={cn( "text-base font-semibold leading-tight tracking-tight", - className, + className )} {...props} /> diff --git a/src/frontend/src/components/ui/checkbox.tsx b/src/frontend/src/components/ui/checkbox.tsx index 1c3d1e4fe..2c48fde84 100644 --- a/src/frontend/src/components/ui/checkbox.tsx +++ b/src/frontend/src/components/ui/checkbox.tsx @@ -13,7 +13,7 @@ const Checkbox = React.forwardRef< ref={ref} className={cn( "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground", - className, + className )} {...props} > @@ -37,7 +37,7 @@ const CheckBoxDiv = ({ className={cn( className, "peer h-4 w-4 shrink-0 rounded-sm border border-primary ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50", - checked ? "bg-primary text-primary-foreground" : "", + checked ? "bg-primary text-primary-foreground" : "" )} > {checked && ( diff --git a/src/frontend/src/components/ui/custom-accordion.tsx b/src/frontend/src/components/ui/custom-accordion.tsx index 507649ca5..9ce39b8a7 100644 --- a/src/frontend/src/components/ui/custom-accordion.tsx +++ b/src/frontend/src/components/ui/custom-accordion.tsx @@ -24,7 +24,7 @@ const AccordionTrigger = React.forwardRef<
    svg]:rotate-180", - className, + className )} > {children} @@ -43,7 +43,7 @@ const AccordionContent = React.forwardRef< ref={ref} className={cn( "data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down overflow-hidden border-[1px] text-sm data-[state=open]:rounded-b-md data-[state=open]:border-t-0 data-[state=open]:bg-muted", - className, + className )} {...props} > diff --git a/src/frontend/src/components/ui/form.tsx b/src/frontend/src/components/ui/form.tsx index 69789b6f3..dcfd39449 100644 --- a/src/frontend/src/components/ui/form.tsx +++ b/src/frontend/src/components/ui/form.tsx @@ -16,18 +16,18 @@ const Form = FormProvider; type FormFieldContextValue< TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath, + TName extends FieldPath = FieldPath > = { name: TName; }; const FormFieldContext = React.createContext( - {} as FormFieldContextValue, + {} as FormFieldContextValue ); const FormField = < TFieldValues extends FieldValues = FieldValues, - TName extends FieldPath = FieldPath, + TName extends FieldPath = FieldPath >({ ...props }: ControllerProps) => { @@ -66,7 +66,7 @@ type FormItemContextValue = { }; const FormItemContext = React.createContext( - {} as FormItemContextValue, + {} as FormItemContextValue ); const FormItem = React.forwardRef< diff --git a/src/frontend/src/components/ui/select-custom.tsx b/src/frontend/src/components/ui/select-custom.tsx index 82ba540fe..86a7bf3ac 100644 --- a/src/frontend/src/components/ui/select-custom.tsx +++ b/src/frontend/src/components/ui/select-custom.tsx @@ -36,7 +36,7 @@ const SelectContent = React.forwardRef< "relative z-50 min-w-[14rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", position === "popper" && "data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1", - className, + className )} position={position} {...props} @@ -45,7 +45,7 @@ const SelectContent = React.forwardRef< className={cn( "p-1", position === "popper" && - "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]", + "h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]" )} > {children} @@ -75,7 +75,7 @@ const SelectItem = React.forwardRef< ref={ref} className={cn( "relative flex w-full cursor-pointer select-none items-center rounded-sm py-1.5 pl-3 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50", - className, + className )} {...props} > diff --git a/src/frontend/src/components/ui/toggle.tsx b/src/frontend/src/components/ui/toggle.tsx index f41840dce..08ebb1380 100644 --- a/src/frontend/src/components/ui/toggle.tsx +++ b/src/frontend/src/components/ui/toggle.tsx @@ -25,7 +25,7 @@ const toggleVariants = cva( variant: "default", size: "default", }, - }, + } ); const Toggle = React.forwardRef< diff --git a/src/frontend/src/components/ui/tooltip.tsx b/src/frontend/src/components/ui/tooltip.tsx index 3ee8b9c7a..7f81bc3bd 100644 --- a/src/frontend/src/components/ui/tooltip.tsx +++ b/src/frontend/src/components/ui/tooltip.tsx @@ -20,7 +20,7 @@ const TooltipContent = React.forwardRef< sideOffset={sideOffset} className={cn( "z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", - className, + className )} {...props} /> @@ -37,7 +37,7 @@ const TooltipContentWithoutPortal = React.forwardRef< sideOffset={sideOffset} className={cn( "z-45 overflow-y-auto rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1", - className, + className )} {...props} /> diff --git a/src/frontend/src/contexts/authContext.tsx b/src/frontend/src/contexts/authContext.tsx index b37816571..1817447f1 100644 --- a/src/frontend/src/contexts/authContext.tsx +++ b/src/frontend/src/contexts/authContext.tsx @@ -30,17 +30,17 @@ export function AuthProvider({ children }): React.ReactElement { const navigate = useNavigate(); const cookies = new Cookies(); const [accessToken, setAccessToken] = useState( - cookies.get("access_token_lf") ?? null, + cookies.get("access_token_lf") ?? null ); const [isAuthenticated, setIsAuthenticated] = useState( - !!cookies.get("access_token_lf"), + !!cookies.get("access_token_lf") ); const [isAdmin, setIsAdmin] = useState(false); const [userData, setUserData] = useState(null); const [autoLogin, setAutoLogin] = useState(false); const setLoading = useAlertStore((state) => state.setLoading); const [apiKey, setApiKey] = useState( - cookies.get("apikey_tkn_lflw"), + cookies.get("apikey_tkn_lflw") ); // const getFoldersApi = useFolderStore((state) => state.getFoldersApi); diff --git a/src/frontend/src/controllers/API/api.tsx b/src/frontend/src/controllers/API/api.tsx index b8035e74e..2a305cf5a 100644 --- a/src/frontend/src/controllers/API/api.tsx +++ b/src/frontend/src/controllers/API/api.tsx @@ -48,7 +48,7 @@ function ApiInterceptor() { } await clearBuildVerticesState(error); return Promise.reject(error); - }, + } ); const isAuthorizedURL = (url) => { @@ -65,10 +65,10 @@ function ApiInterceptor() { const parsedURL = new URL(url); const isDomainAllowed = authorizedDomains.some( - (domain) => parsedURL.origin === new URL(domain).origin, + (domain) => parsedURL.origin === new URL(domain).origin ); const isEndpointAllowed = authorizedEndpoints.some((endpoint) => - parsedURL.pathname.includes(endpoint), + parsedURL.pathname.includes(endpoint) ); return isDomainAllowed || isEndpointAllowed; @@ -101,7 +101,7 @@ function ApiInterceptor() { }, (error) => { return Promise.reject(error); - }, + } ); return () => { @@ -133,7 +133,7 @@ function ApiInterceptor() { if (error?.config?.headers) { delete error.config.headers["Authorization"]; error.config.headers["Authorization"] = `Bearer ${cookies.get( - "access_token_lf", + "access_token_lf" )}`; const response = await axios.request(error.config); return response; diff --git a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts index 79a47c7a7..6486de541 100644 --- a/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts +++ b/src/frontend/src/controllers/API/helpers/check-duplicate-requests.ts @@ -8,7 +8,7 @@ export function checkDuplicateRequestAndStoreRequest(config) { const currentTime = Date.now(); const isContained = AUTHORIZED_DUPLICATE_REQUESTS.some((request) => - config?.url!.includes(request), + config?.url!.includes(request) ); if ( diff --git a/src/frontend/src/controllers/API/index.ts b/src/frontend/src/controllers/API/index.ts index 91068832e..07a9cd06d 100644 --- a/src/frontend/src/controllers/API/index.ts +++ b/src/frontend/src/controllers/API/index.ts @@ -63,7 +63,7 @@ export async function sendAll(data: sendAllProps) { } export async function postValidateCode( - code: string, + code: string ): Promise> { return await api.post(`${BASE_URL_API}validate/code`, { code }); } @@ -78,7 +78,7 @@ export async function postValidateCode( export async function postValidatePrompt( name: string, template: string, - frontend_node: APIClassType, + frontend_node: APIClassType ): Promise> { return api.post(`${BASE_URL_API}validate/prompt`, { name, @@ -151,7 +151,7 @@ export async function saveFlowToDatabase(newFlow: { * @throws Will throw an error if the update fails. */ export async function updateFlowInDatabase( - updatedFlow: FlowType, + updatedFlow: FlowType ): Promise { try { const response = await api.patch(`${BASE_URL_API}flows/${updatedFlow.id}`, { @@ -329,7 +329,7 @@ export async function getHealth() { * */ export async function getBuildStatus( - flowId: string, + flowId: string ): Promise> { return await api.get(`${BASE_URL_API}build/${flowId}/status`); } @@ -342,7 +342,7 @@ export async function getBuildStatus( * */ export async function postBuildInit( - flow: FlowType, + flow: FlowType ): Promise> { return await api.post(`${BASE_URL_API}build/init/${flow.id}`, flow); } @@ -358,7 +358,7 @@ export async function postBuildInit( */ export async function uploadFile( file: File, - id: string, + id: string ): Promise> { const formData = new FormData(); formData.append("file", file); @@ -380,7 +380,7 @@ export async function getProfilePictures(): Promise> { // let template = apiClass.template; return await api.post(`${BASE_URL_API}custom_component`, { @@ -393,7 +393,7 @@ export async function postCustomComponentUpdate( code: string, template: APITemplateType, field: string, - field_value: any, + field_value: any ): Promise> { return await api.post(`${BASE_URL_API}custom_component/update`, { code, @@ -415,7 +415,7 @@ export async function onLogin(user: LoginType) { headers: { "Content-Type": "application/x-www-form-urlencoded", }, - }, + } ); if (response.status === 200) { @@ -477,11 +477,11 @@ export async function addUser(user: UserInputType): Promise> { export async function getUsersPage( skip: number, - limit: number, + limit: number ): Promise> { try { const res = await api.get( - `${BASE_URL_API}users/?skip=${skip}&limit=${limit}`, + `${BASE_URL_API}users/?skip=${skip}&limit=${limit}` ); if (res.status === 200) { return res.data; @@ -518,7 +518,7 @@ export async function resetPassword(user_id: string, user: resetPasswordType) { try { const res = await api.patch( `${BASE_URL_API}users/${user_id}/reset-password`, - user, + user ); if (res.status === 200) { return res.data; @@ -592,7 +592,7 @@ export async function saveFlowStore( last_tested_version?: string; }, tags: string[], - publicFlow = false, + publicFlow = false ): Promise { try { const response = await api.post(`${BASE_URL_API}store/components/`, { @@ -721,7 +721,7 @@ export async function postStoreComponents(component: Component) { export async function getComponent(component_id: string) { try { const res = await api.get( - `${BASE_URL_API}store/components/${component_id}`, + `${BASE_URL_API}store/components/${component_id}` ); if (res.status === 200) { return res.data; @@ -736,7 +736,7 @@ export async function searchComponent( page?: number | null, limit?: number | null, status?: string | null, - tags?: string[], + tags?: string[] ): Promise { try { let url = `${BASE_URL_API}store/components/`; @@ -848,7 +848,7 @@ export async function updateFlowStore( }, tags: string[], publicFlow = false, - id: string, + id: string ): Promise { try { const response = await api.patch(`${BASE_URL_API}store/components/${id}`, { @@ -932,7 +932,7 @@ export async function deleteGlobalVariable(id: string) { export async function updateGlobalVariable( name: string, value: string, - id: string, + id: string ) { try { const response = api.patch(`${BASE_URL_API}variables/${id}`, { @@ -951,7 +951,7 @@ export async function getVerticesOrder( startNodeId?: string | null, stopNodeId?: string | null, nodes?: Node[], - Edges?: Edge[], + Edges?: Edge[] ): Promise> { // nodeId is optional and is a query parameter // if nodeId is not provided, the API will return all vertices @@ -971,7 +971,7 @@ export async function getVerticesOrder( return await api.post( `${BASE_URL_API}build/${flowId}/vertices`, data, - config, + config ); } @@ -979,7 +979,7 @@ export async function postBuildVertex( flowId: string, vertexId: string, input_value: string, - files?: string[], + files?: string[] ): Promise> { // input_value is optional and is a query parameter let data = {}; @@ -991,7 +991,7 @@ export async function postBuildVertex( } return await api.post( `${BASE_URL_API}build/${flowId}/vertices/${vertexId}`, - data, + data ); } @@ -1015,7 +1015,7 @@ export async function getFlowPool({ } export async function deleteFlowPool( - flowId: string, + flowId: string ): Promise> { const config = {}; config["params"] = { flow_id: flowId }; @@ -1029,7 +1029,7 @@ export async function deleteFlowPool( * @returns A promise that resolves to an array of AxiosResponse objects representing the delete responses. */ export async function multipleDeleteFlowsComponents( - flowIds: string[], + flowIds: string[] ): Promise[]> { const batches: string[][] = []; @@ -1052,7 +1052,7 @@ export async function multipleDeleteFlowsComponents( // Execute all delete requests const responses: Promise>[] = batches.map((batch) => - deleteBatch(batch), + deleteBatch(batch) ); // Return the responses after all requests are completed @@ -1062,7 +1062,7 @@ export async function multipleDeleteFlowsComponents( export async function getTransactionTable( id: string, mode: "intersection" | "union", - params = {}, + params = {} ): Promise<{ rows: Array; columns: Array }> { const config = {}; config["params"] = { flow_id: id }; @@ -1078,7 +1078,7 @@ export async function getMessagesTable( mode: "intersection" | "union", id?: string, excludedFields?: string[], - params = {}, + params = {} ): Promise<{ rows: Array; columns: Array }> { const config = {}; if (id) { diff --git a/src/frontend/src/icons/Groq/index.tsx b/src/frontend/src/icons/Groq/index.tsx index 6c4283d29..291696154 100644 --- a/src/frontend/src/icons/Groq/index.tsx +++ b/src/frontend/src/icons/Groq/index.tsx @@ -4,5 +4,5 @@ import SvgGroqLogo from "./GroqLogo"; export const GroqIcon = forwardRef>( (props, ref) => { return ; - }, + } ); diff --git a/src/frontend/src/icons/Streamlit/index.tsx b/src/frontend/src/icons/Streamlit/index.tsx index 1a4c55119..6b3391021 100644 --- a/src/frontend/src/icons/Streamlit/index.tsx +++ b/src/frontend/src/icons/Streamlit/index.tsx @@ -4,5 +4,5 @@ import SvgStreamlit from "./SvgStreamlit"; export const Streamlit = forwardRef>( (props, ref) => { return ; - }, + } ); diff --git a/src/frontend/src/index.tsx b/src/frontend/src/index.tsx index 006d93ff2..78a57298f 100644 --- a/src/frontend/src/index.tsx +++ b/src/frontend/src/index.tsx @@ -11,11 +11,11 @@ import "./style/applies.css"; import "./style/classes.css"; const root = ReactDOM.createRoot( - document.getElementById("root") as HTMLElement, + document.getElementById("root") as HTMLElement ); root.render( - , + ); reportWebVitals(); diff --git a/src/frontend/src/modals/BundleModal/hooks/submit-folder.tsx b/src/frontend/src/modals/BundleModal/hooks/submit-folder.tsx index cb12ca7cb..1347a323b 100644 --- a/src/frontend/src/modals/BundleModal/hooks/submit-folder.tsx +++ b/src/frontend/src/modals/BundleModal/hooks/submit-folder.tsx @@ -27,7 +27,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => { getFoldersApi(true); setOpen(false); } - }, + } ); } else { addFolder(data).then( @@ -42,7 +42,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => { setErrorData({ title: `Error creating folder.`, }); - }, + } ); } }; diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/components/csvSelect/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/components/csvSelect/index.tsx index 5adb156ef..1438237b7 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/components/csvSelect/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/components/csvSelect/index.tsx @@ -29,7 +29,7 @@ export default function CsvSelect({ node, handleChangeSelect }): JSX.Element { {separator} - ), + ) )} diff --git a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx index 20bae05c6..1ee08100e 100644 --- a/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/IOFieldView/index.tsx @@ -50,7 +50,7 @@ export default function IOFieldView({ .results.result ?? ""; console.log( - (flowPool[node!.id] ?? [])[(flowPool[node!.id]?.length ?? 1) - 1]?.data, + (flowPool[node!.id] ?? [])[(flowPool[node!.id]?.length ?? 1) - 1]?.data ); function handleOutputType() { @@ -257,7 +257,7 @@ export default function IOFieldView({ rows={ Array.isArray(flowPoolNode?.data?.artifacts) ? flowPoolNode?.data?.artifacts?.map( - (artifact) => artifact.data, + (artifact) => artifact.data ) ?? [] : [flowPoolNode?.data?.artifacts] } diff --git a/src/frontend/src/modals/IOModal/components/SessionView/hooks/index.tsx b/src/frontend/src/modals/IOModal/components/SessionView/hooks/index.tsx index e8e638def..738ea9977 100644 --- a/src/frontend/src/modals/IOModal/components/SessionView/hooks/index.tsx +++ b/src/frontend/src/modals/IOModal/components/SessionView/hooks/index.tsx @@ -10,7 +10,7 @@ const useRemoveSession = (setSuccessData, setErrorData) => { await deleteMessagesFn( messages .filter((msg) => msg.session_id === session_id) - .map((msg) => msg.index), + .map((msg) => msg.index) ); deleteSession(session_id); setSuccessData({ diff --git a/src/frontend/src/modals/IOModal/components/SessionView/index.tsx b/src/frontend/src/modals/IOModal/components/SessionView/index.tsx index edabbe252..a7fc91b03 100644 --- a/src/frontend/src/modals/IOModal/components/SessionView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/SessionView/index.tsx @@ -17,7 +17,7 @@ export default function SessionView({ rows }: { rows: Array }) { setSelectedRows, setSuccessData, setErrorData, - selectedRows, + selectedRows ); const { handleUpdate } = useUpdateMessage(setSuccessData, setErrorData); diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/buttonSendWrapper/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/buttonSendWrapper/index.tsx index bf61b2fb9..bf0600a5d 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/buttonSendWrapper/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/buttonSendWrapper/index.tsx @@ -28,8 +28,8 @@ const ButtonSendWrapper = ({ noInput ? "bg-high-indigo text-background" : chatValue === "" - ? "text-primary" - : "bg-chat-send text-background", + ? "text-primary" + : "bg-chat-send text-background" )} disabled={lockChat || saveLoading} onClick={(): void => send()} diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/textAreaWrapper/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/textAreaWrapper/index.tsx index 29f88453a..3d41e51f4 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/textAreaWrapper/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/components/textAreaWrapper/index.tsx @@ -18,7 +18,7 @@ const TextAreaWrapper = ({ }) => { const getPlaceholderText = ( isDragging: boolean, - noInput: boolean, + noInput: boolean ): string => { if (isDragging) { return "Drop here"; @@ -33,8 +33,8 @@ const TextAreaWrapper = ({ lockChat || saveLoading ? "form-modal-lock-true bg-input" : noInput - ? "form-modal-no-input bg-input" - : "form-modal-lock-false bg-background"; + ? "form-modal-no-input bg-input" + : "form-modal-lock-false bg-background"; const fileClass = files.length > 0 diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx index c85617ab2..141754cbd 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-drag-and-drop.tsx @@ -9,7 +9,7 @@ const useDragAndDrop = ( setIsDragging, setFiles, currentFlowId, - setErrorData, + setErrorData ) => { const dragOver = (e) => { e.preventDefault(); diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-handle-file-change.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-handle-file-change.tsx index 6316bf0c0..060481cd5 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-handle-file-change.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/hooks/use-handle-file-change.tsx @@ -9,7 +9,7 @@ const snErrorTxt = "png, jpg, jpeg"; export const useHandleFileChange = (setFiles, currentFlowId) => { const setErrorData = useAlertStore((state) => state.setErrorData); const handleFileChange = async ( - event: React.ChangeEvent, + event: React.ChangeEvent ) => { const fileInput = event.target; const file = fileInput.files?.[0]; diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx index a3c070a5f..4311f0ed2 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatInput/index.tsx @@ -116,7 +116,7 @@ export default function ChatInput({ key={file.id} onDelete={() => { setFiles((prev: FilePreviewType[]) => - prev.filter((f) => f.id !== file.id), + prev.filter((f) => f.id !== file.id) ); // TODO: delete file on backend }} diff --git a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/index.tsx index 1d4b11667..d6451d1ae 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/chatMessage/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/chatMessage/index.tsx @@ -115,19 +115,19 @@ export default function ChatMessage({
    ), - [chat.message, chatMessage], + [chat.message, chatMessage] )}
    @@ -292,7 +292,7 @@ dark:prose-invert" parts.push( {chat.message[match[1]]} - , + ); } diff --git a/src/frontend/src/modals/IOModal/components/chatView/fileComponent/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/fileComponent/index.tsx index a034b1c40..7b56cdcc0 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/fileComponent/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/fileComponent/index.tsx @@ -29,7 +29,7 @@ export default function FileCard({ const imgSrc = `${BACKEND_URL.slice( 0, - BACKEND_URL.length - 1, + BACKEND_URL.length - 1 )}${BASE_URL_API}files/images/${content}`; console.log(imgSrc); diff --git a/src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/handle-download.tsx b/src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/handle-download.tsx index a4be91d50..e82bf3167 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/handle-download.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/fileComponent/utils/handle-download.tsx @@ -20,8 +20,8 @@ export default async function handleDownload({ const response = await fetch( `${BACKEND_URL.slice( 0, - BACKEND_URL.length - 1, - )}${BASE_URL_API}files/download/${content}`, + BACKEND_URL.length - 1 + )}${BASE_URL_API}files/download/${content}` ); if (!response.ok) { throw new Error("Network response was not ok"); diff --git a/src/frontend/src/modals/IOModal/components/chatView/filePreviewChat/utils/format-file-name.tsx b/src/frontend/src/modals/IOModal/components/chatView/filePreviewChat/utils/format-file-name.tsx index 94258b6af..b474f8294 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/filePreviewChat/utils/format-file-name.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/filePreviewChat/utils/format-file-name.tsx @@ -1,6 +1,6 @@ export default function formatFileName( name: string, - numberToTruncate: number = 25, + numberToTruncate: number = 25 ): string { if (name[numberToTruncate] === undefined) { return name; diff --git a/src/frontend/src/modals/IOModal/components/chatView/index.tsx b/src/frontend/src/modals/IOModal/components/chatView/index.tsx index 736d21a6f..d4d4c8080 100644 --- a/src/frontend/src/modals/IOModal/components/chatView/index.tsx +++ b/src/frontend/src/modals/IOModal/components/chatView/index.tsx @@ -58,7 +58,7 @@ export default function ChatView({ // .filter( (output) => - output.data.message || (!output.data.message && output.artifacts), + output.data.message || (!output.data.message && output.artifacts) ) .map((output, index) => { try { @@ -139,7 +139,7 @@ export default function ChatView({ function updateChat( chat: ChatMessageType, message: string, - stream_url?: string, + stream_url?: string ) { chat.message = message; updateFlowPool(chat.componentId, { @@ -155,7 +155,7 @@ export default function ChatView({ setIsDragging, setFiles, currentFlowId, - setErrorData, + setErrorData ); return ( diff --git a/src/frontend/src/modals/IOModal/index.tsx b/src/frontend/src/modals/IOModal/index.tsx index 2730dceb9..f1dc14182 100644 --- a/src/frontend/src/modals/IOModal/index.tsx +++ b/src/frontend/src/modals/IOModal/index.tsx @@ -36,25 +36,25 @@ export default function IOModal({ const allNodes = useFlowStore((state) => state.nodes); const setMessages = useMessagesStore((state) => state.setMessages); const inputs = useFlowStore((state) => state.inputs).filter( - (input) => input.type !== "ChatInput", + (input) => input.type !== "ChatInput" ); const chatInput = useFlowStore((state) => state.inputs).find( - (input) => input.type === "ChatInput", + (input) => input.type === "ChatInput" ); const outputs = useFlowStore((state) => state.outputs).filter( - (output) => output.type !== "ChatOutput", + (output) => output.type !== "ChatOutput" ); const chatOutput = useFlowStore((state) => state.outputs).find( - (output) => output.type === "ChatOutput", + (output) => output.type === "ChatOutput" ); const nodes = useFlowStore((state) => state.nodes).filter( (node) => inputs.some((input) => input.id === node.id) || - outputs.some((output) => output.id === node.id), + outputs.some((output) => output.id === node.id) ); const haveChat = chatInput || chatOutput; const [selectedTab, setSelectedTab] = useState( - inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0, + inputs.length > 0 ? 1 : outputs.length > 0 ? 2 : 0 ); const setErrorData = useAlertStore((state) => state.setErrorData); const setSuccessData = useAlertStore((state) => state.setSuccessData); @@ -131,7 +131,7 @@ export default function IOModal({ const { handleRemoveSession } = useRemoveSession( setSuccessData, - setErrorData, + setErrorData ); useEffect(() => { @@ -155,7 +155,7 @@ export default function IOModal({ ({ rows, columns }) => { setMessages(rows); setColumns(columns); - }, + } ); } }, [open]); @@ -194,7 +194,7 @@ export default function IOModal({
    {nodes .filter((node) => - inputs.some((input) => input.id === node.id), + inputs.some((input) => input.id === node.id) ) .map((node, index) => { const input = inputs.find( - (input) => input.id === node.id, + (input) => input.id === node.id )!; return (
    {nodes .filter((node) => - outputs.some((output) => output.id === node.id), + outputs.some((output) => output.id === node.id) ) .map((node, index) => { const output = outputs.find( - (output) => output.id === node.id, + (output) => output.id === node.id )!; const textOutputValue = (flowPool[node!.id] ?? [])[ @@ -439,7 +439,7 @@ export default function IOModal({
    @@ -458,7 +458,7 @@ export default function IOModal({
    {inputs.some( - (input) => input.id === selectedViewField.id, + (input) => input.id === selectedViewField.id ) && ( )} {outputs.some( - (output) => output.id === selectedViewField.id, + (output) => output.id === selectedViewField.id ) && ( )} {sessions.some( - (session) => session === selectedViewField.id, + (session) => session === selectedViewField.id ) && ( - message.session_id === selectedViewField.id, + message.session_id === selectedViewField.id )} /> )} @@ -493,7 +493,7 @@ export default function IOModal({
    {haveChat ? ( @@ -525,7 +525,7 @@ export default function IOModal({ "h-4 w-4", isBuilding ? "animate-spin" - : "fill-current text-medium-indigo", + : "fill-current text-medium-indigo" )} /> ), diff --git a/src/frontend/src/modals/apiModal/index.tsx b/src/frontend/src/modals/apiModal/index.tsx index ead038ad2..19f506459 100644 --- a/src/frontend/src/modals/apiModal/index.tsx +++ b/src/frontend/src/modals/apiModal/index.tsx @@ -39,7 +39,7 @@ const ApiModal = forwardRef( open?: boolean; setOpen?: (a: boolean | ((o?: boolean) => boolean)) => void; }, - ref, + ref ) => { const tweak = useTweaksStore((state) => state.tweak); const addTweaks = useTweaksStore((state) => state.setTweak); @@ -57,18 +57,18 @@ const ApiModal = forwardRef( flow?.id, autoLogin, tweak, - flow?.endpoint_name, + flow?.endpoint_name ); const curl_run_code = getCurlRunCode( flow?.id, autoLogin, tweak, - flow?.endpoint_name, + flow?.endpoint_name ); const curl_webhook_code = getCurlWebhookCode( flow?.id, autoLogin, - flow?.endpoint_name, + flow?.endpoint_name ); const pythonCode = getPythonCode(flow?.name, tweak); const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); @@ -83,7 +83,7 @@ const ApiModal = forwardRef( pythonCode, ]; const [tabs, setTabs] = useState( - createTabsArray(codesArray, includeWebhook), + createTabsArray(codesArray, includeWebhook) ); const canShowTweaks = @@ -132,7 +132,7 @@ const ApiModal = forwardRef( buildTweakObject( nodeId, element.data.node.template[templateField].value, - element.data.node.template[templateField], + element.data.node.template[templateField] ); } }); @@ -149,7 +149,7 @@ const ApiModal = forwardRef( async function buildTweakObject( tw: string, changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType, + template: TemplateVariableType ) { changes = getChangesType(changes, template); @@ -191,7 +191,7 @@ const ApiModal = forwardRef( flow?.id, autoLogin, cloneTweak, - flow?.endpoint_name, + flow?.endpoint_name ); const pythonCode = getPythonCode(flow?.name, cloneTweak); const widgetCode = getWidgetCode(flow?.id, flow?.name, autoLogin); @@ -235,7 +235,7 @@ const ApiModal = forwardRef( ); - }, + } ); export default ApiModal; diff --git a/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts b/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts index 5a859cae8..592a812c4 100644 --- a/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts +++ b/src/frontend/src/modals/apiModal/utils/check-can-build-tweak-object.ts @@ -6,7 +6,7 @@ export const checkCanBuildTweakObject = (element, templateField) => { templateField.charAt(0) !== "_" && element.data.node.template[templateField].show && LANGFLOW_SUPPORTED_TYPES.has( - element.data.node.template[templateField].type, + element.data.node.template[templateField].type ) && templateField !== "code" ); diff --git a/src/frontend/src/modals/apiModal/utils/get-changes-types.ts b/src/frontend/src/modals/apiModal/utils/get-changes-types.ts index e8e912ff3..7e295e358 100644 --- a/src/frontend/src/modals/apiModal/utils/get-changes-types.ts +++ b/src/frontend/src/modals/apiModal/utils/get-changes-types.ts @@ -3,7 +3,7 @@ import { convertArrayToObj } from "../../../utils/reactflowUtils"; export const getChangesType = ( changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType, + template: TemplateVariableType ) => { if (typeof changes === "string" && template.type === "float") { changes = parseFloat(changes); diff --git a/src/frontend/src/modals/apiModal/utils/get-curl-code.tsx b/src/frontend/src/modals/apiModal/utils/get-curl-code.tsx index c17118d1a..40257d73d 100644 --- a/src/frontend/src/modals/apiModal/utils/get-curl-code.tsx +++ b/src/frontend/src/modals/apiModal/utils/get-curl-code.tsx @@ -8,14 +8,14 @@ export function getCurlRunCode( flowId: string, isAuth: boolean, tweaksBuildedObject, - endpointName?: string, + endpointName?: string ): string { const tweaksObject = tweaksBuildedObject[0]; // show the endpoint name in the curl command if it exists return `curl -X POST \\ "${window.location.protocol}//${window.location.host}/api/v1/run/${ - endpointName || flowId - }?stream=false" \\ + endpointName || flowId + }?stream=false" \\ -H 'Content-Type: application/json'\\${ !isAuth ? `\n -H 'x-api-key: '\\` : "" } diff --git a/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts b/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts index 4cd3763c6..657526dda 100644 --- a/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts +++ b/src/frontend/src/modals/apiModal/utils/get-nodes-with-default-value.ts @@ -13,8 +13,8 @@ export const getNodesWithDefaultValue = (flow) => { templateField.charAt(0) !== "_" && node.data.node.template[templateField]?.show && LANGFLOW_SUPPORTED_TYPES.has( - node.data.node.template[templateField]?.type, - ), + node.data.node.template[templateField]?.type + ) ) .map((n, i) => { arrNodesWithValues.push(node["id"]); diff --git a/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx b/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx index 9aa946746..a876b18c3 100644 --- a/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx +++ b/src/frontend/src/modals/apiModal/utils/get-python-api-code.tsx @@ -10,7 +10,7 @@ export default function getPythonApiCode( flowId: string, isAuth: boolean, tweaksBuildedObject: any[], - endpointName?: string, + endpointName?: string ): string { let tweaksString = "{}"; if (tweaksBuildedObject && tweaksBuildedObject.length > 0) { diff --git a/src/frontend/src/modals/apiModal/utils/get-python-code.tsx b/src/frontend/src/modals/apiModal/utils/get-python-code.tsx index 734e16bbe..846a4c6e9 100644 --- a/src/frontend/src/modals/apiModal/utils/get-python-code.tsx +++ b/src/frontend/src/modals/apiModal/utils/get-python-code.tsx @@ -6,7 +6,7 @@ */ export default function getPythonCode( flowName: string, - tweaksBuildedObject: any[], + tweaksBuildedObject: any[] ): string { let tweaksString = "{}"; if (tweaksBuildedObject && tweaksBuildedObject.length > 0) { diff --git a/src/frontend/src/modals/apiModal/utils/get-value.ts b/src/frontend/src/modals/apiModal/utils/get-value.ts index df8e5bdde..8db7666bf 100644 --- a/src/frontend/src/modals/apiModal/utils/get-value.ts +++ b/src/frontend/src/modals/apiModal/utils/get-value.ts @@ -5,7 +5,7 @@ export const getValue = ( value: string, node: NodeType, template: TemplateVariableType, - tweak: Object[], + tweak: Object[] ) => { let returnValue = value ?? ""; diff --git a/src/frontend/src/modals/apiModal/utils/get-widget-code.tsx b/src/frontend/src/modals/apiModal/utils/get-widget-code.tsx index 0d3d02f91..a05dc192a 100644 --- a/src/frontend/src/modals/apiModal/utils/get-widget-code.tsx +++ b/src/frontend/src/modals/apiModal/utils/get-widget-code.tsx @@ -6,7 +6,7 @@ export default function getWidgetCode( flowId: string, flowName: string, - isAuth: boolean, + isAuth: boolean ): string { return ` diff --git a/src/frontend/src/modals/apiModal/utils/tabs-array.tsx b/src/frontend/src/modals/apiModal/utils/tabs-array.tsx index deed73332..adc15f932 100644 --- a/src/frontend/src/modals/apiModal/utils/tabs-array.tsx +++ b/src/frontend/src/modals/apiModal/utils/tabs-array.tsx @@ -1,7 +1,7 @@ export function createTabsArray( codes, includeWebhookCurl = false, - includeTweaks = false, + includeTweaks = false ) { const tabs = [ { diff --git a/src/frontend/src/modals/baseModal/index.tsx b/src/frontend/src/modals/baseModal/index.tsx index 3ee7788af..834c367b3 100644 --- a/src/frontend/src/modals/baseModal/index.tsx +++ b/src/frontend/src/modals/baseModal/index.tsx @@ -37,7 +37,7 @@ const Content: React.FC = ({ children, overflowHidden }) => {
    {children} @@ -122,7 +122,7 @@ interface BaseModalProps { React.ReactElement, React.ReactElement, React.ReactElement?, - React.ReactElement?, + React.ReactElement? ]; open?: boolean; setOpen?: (open: boolean) => void; @@ -158,16 +158,16 @@ function BaseModal({ onSubmit, }: BaseModalProps) { const headerChild = React.Children.toArray(children).find( - (child) => (child as React.ReactElement).type === Header, + (child) => (child as React.ReactElement).type === Header ); const triggerChild = React.Children.toArray(children).find( - (child) => (child as React.ReactElement).type === Trigger, + (child) => (child as React.ReactElement).type === Trigger ); const ContentChild = React.Children.toArray(children).find( - (child) => (child as React.ReactElement).type === Content, + (child) => (child as React.ReactElement).type === Content ); const ContentFooter = React.Children.toArray(children).find( - (child) => (child as React.ReactElement).type === Footer, + (child) => (child as React.ReactElement).type === Footer ); let { minWidth, height } = switchCaseModalSize(size); @@ -189,7 +189,7 @@ function BaseModal({ const contentClasses = cn( minWidth, height, - "flex flex-col duration-300 overflow-hidden", + "flex flex-col duration-300 overflow-hidden" ); //UPDATE COLORS AND STYLE CLASSSES diff --git a/src/frontend/src/modals/dictAreaModal/index.tsx b/src/frontend/src/modals/dictAreaModal/index.tsx index afcab7857..77887f478 100644 --- a/src/frontend/src/modals/dictAreaModal/index.tsx +++ b/src/frontend/src/modals/dictAreaModal/index.tsx @@ -4,6 +4,7 @@ import "ace-builds/src-noconflict/mode-python"; import "ace-builds/src-noconflict/theme-github"; import "ace-builds/src-noconflict/theme-twilight"; // import "ace-builds/webpack-resolver"; +import { cloneDeep } from "lodash"; import { useEffect, useState } from "react"; import JsonView from "react18-json-view"; import "react18-json-view/src/dark.css"; @@ -12,7 +13,6 @@ import IconComponent from "../../components/genericIconComponent"; import { CODE_DICT_DIALOG_SUBTITLE } from "../../constants/constants"; import { useDarkStore } from "../../stores/darkStore"; import BaseModal from "../baseModal"; -import { cloneDeep } from "lodash"; export default function DictAreaModal({ children, diff --git a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx index 14263a9c6..83590f409 100644 --- a/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx +++ b/src/frontend/src/modals/editNodeModal/hooks/use-column-defs.tsx @@ -8,7 +8,7 @@ const useColumnDefs = ( handleOnNewValue: (newValue: any, name: string) => void, handleOnChangeDb: (value: boolean, key: string) => void, changeAdvanced: (n: string) => void, - open: boolean, + open: boolean ) => { const columnDefs: ColDef[] = useMemo( () => [ @@ -76,7 +76,7 @@ const useColumnDefs = ( cellClass: "no-border", }, ], - [open, myData], + [open, myData] ); return columnDefs; diff --git a/src/frontend/src/modals/editNodeModal/index.tsx b/src/frontend/src/modals/editNodeModal/index.tsx index b8e6a11a5..05a3a4354 100644 --- a/src/frontend/src/modals/editNodeModal/index.tsx +++ b/src/frontend/src/modals/editNodeModal/index.tsx @@ -1,6 +1,6 @@ import { ColDef, GridApi } from "ag-grid-community"; +import { cloneDeep } from "lodash"; import { forwardRef, useEffect, useRef, useState } from "react"; -import IconComponent from "../../components/genericIconComponent"; import TableComponent from "../../components/tableComponent"; import { Badge } from "../../components/ui/badge"; import { useDarkStore } from "../../stores/darkStore"; @@ -9,7 +9,6 @@ import { NodeDataType } from "../../types/flow"; import BaseModal from "../baseModal"; import useColumnDefs from "./hooks/use-column-defs"; import useRowData from "./hooks/use-row-data"; -import { cloneDeep } from "lodash"; const EditNodeModal = forwardRef( ( @@ -26,7 +25,7 @@ const EditNodeModal = forwardRef( // setOpenWDoubleClick: (open: boolean) => void; data: NodeDataType; }, - ref, + ref ) => { const myData = useRef(cloneDeep(data)); @@ -54,7 +53,7 @@ const EditNodeModal = forwardRef( handleOnNewValue, handleOnChangeDb, changeAdvanced, - open, + open ); const [gridApi, setGridApi] = useState(null); @@ -118,7 +117,7 @@ const EditNodeModal = forwardRef( /> ); - }, + } ); export default EditNodeModal; diff --git a/src/frontend/src/modals/exportModal/index.tsx b/src/frontend/src/modals/exportModal/index.tsx index b7e7e0f9d..9ed28def8 100644 --- a/src/frontend/src/modals/exportModal/index.tsx +++ b/src/frontend/src/modals/exportModal/index.tsx @@ -45,7 +45,7 @@ const ExportModal = forwardRef( is_component: false, }, name!, - description, + description ); setNoticeData({ title: API_WARNING_NOTICE_ALERT, @@ -61,7 +61,7 @@ const ExportModal = forwardRef( is_component: false, }), name!, - description, + description ); setOpen(false); }} @@ -102,6 +102,6 @@ const ExportModal = forwardRef( ); - }, + } ); export default ExportModal; diff --git a/src/frontend/src/modals/flowLogsModal/index.tsx b/src/frontend/src/modals/flowLogsModal/index.tsx index 1ba42f9eb..840de14ca 100644 --- a/src/frontend/src/modals/flowLogsModal/index.tsx +++ b/src/frontend/src/modals/flowLogsModal/index.tsx @@ -37,7 +37,7 @@ export default function FlowLogsModal({ const { columns, rows } = data; setColumns(columns.map((col) => ({ ...col, editable: true }))); setRows(rows); - }, + } ); } @@ -47,7 +47,7 @@ export default function FlowLogsModal({ .some((template) => template["stream"] && template["stream"].value); console.log( haStream, - nodes.map((nodes) => (nodes.data as NodeDataType).node!.template), + nodes.map((nodes) => (nodes.data as NodeDataType).node!.template) ); if (haStream) { setNoticeData({ diff --git a/src/frontend/src/modals/foldersModal/hooks/submit-folder.tsx b/src/frontend/src/modals/foldersModal/hooks/submit-folder.tsx index 71a8ac944..c35d7c450 100644 --- a/src/frontend/src/modals/foldersModal/hooks/submit-folder.tsx +++ b/src/frontend/src/modals/foldersModal/hooks/submit-folder.tsx @@ -33,7 +33,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => { getFoldersApi(true); setOpen(false); } - }, + } ); } else { addFolder(data).then( @@ -49,7 +49,7 @@ const useFolderSubmit = (setOpen, folderToEdit) => { setErrorData({ title: `Error creating folder.`, }); - }, + } ); } }; diff --git a/src/frontend/src/modals/genericModal/index.tsx b/src/frontend/src/modals/genericModal/index.tsx index 326be58db..250192dc9 100644 --- a/src/frontend/src/modals/genericModal/index.tsx +++ b/src/frontend/src/modals/genericModal/index.tsx @@ -83,7 +83,7 @@ export default function GenericModal({ } const filteredWordsHighlight = matches.filter( - (word) => !invalid_chars.includes(word), + (word) => !invalid_chars.includes(word) ); setWordsHighlight(filteredWordsHighlight); @@ -134,7 +134,7 @@ export default function GenericModal({ // to the first key of the custom_fields object if (field_name === "") { field_name = Array.isArray( - apiReturn.data?.frontend_node?.custom_fields?.[""], + apiReturn.data?.frontend_node?.custom_fields?.[""] ) ? apiReturn.data?.frontend_node?.custom_fields?.[""][0] ?? "" : apiReturn.data?.frontend_node?.custom_fields?.[""] ?? ""; @@ -209,7 +209,7 @@ export default function GenericModal({
    {type === TypeModal.PROMPT && isEdit && !readonly ? ( diff --git a/src/frontend/src/modals/newFlowModal/index.tsx b/src/frontend/src/modals/newFlowModal/index.tsx index f9d1f98b2..7e64ed5dc 100644 --- a/src/frontend/src/modals/newFlowModal/index.tsx +++ b/src/frontend/src/modals/newFlowModal/index.tsx @@ -32,7 +32,7 @@ export default function NewFlowModal({ key={0} flow={ examples.find( - (e) => e.name == "Basic Prompting (Hello, World)", + (e) => e.name == "Basic Prompting (Hello, World)" )! } /> diff --git a/src/frontend/src/modals/shareModal/index.tsx b/src/frontend/src/modals/shareModal/index.tsx index ac6832082..0bc66092a 100644 --- a/src/frontend/src/modals/shareModal/index.tsx +++ b/src/frontend/src/modals/shareModal/index.tsx @@ -131,14 +131,14 @@ export default function ShareModal({ title: "Error sharing " + is_component ? "component" : "flow", list: [err["response"]["data"]["detail"]], }); - }, + } ); else updateFlowStore( flow!, getTagsIds(selectedTags, tags), sharePublic, - unavaliableNames.find((e) => e.name === name)!.id, + unavaliableNames.find((e) => e.name === name)!.id ).then(successShare, (err) => { setErrorData({ title: "Error sharing " + is_component ? "component" : "flow", @@ -205,7 +205,7 @@ export default function ShareModal({ setOpen={internalSetOpen} onSubmit={() => { const isNameAvailable = !unavaliableNames.some( - (element) => element.name === name, + (element) => element.name === name ); if (isNameAvailable) { diff --git a/src/frontend/src/modals/shareModal/utils/get-tags-ids.tsx b/src/frontend/src/modals/shareModal/utils/get-tags-ids.tsx index 364d310a5..1eb1c650e 100644 --- a/src/frontend/src/modals/shareModal/utils/get-tags-ids.tsx +++ b/src/frontend/src/modals/shareModal/utils/get-tags-ids.tsx @@ -1,6 +1,6 @@ export default function getTagsIds( tags: string[], - tagListId: { name: string; id: string }[], + tagListId: { name: string; id: string }[] ) { return tags .map((tag) => tagListId.find((tagObj) => tagObj.name === tag))! diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx index 43e6a320c..797fb0368 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/index.tsx @@ -62,19 +62,19 @@ export default function Page({ const preventDefault = true; const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const autoSaveCurrentFlow = useFlowsManagerStore( - (state) => state.autoSaveCurrentFlow, + (state) => state.autoSaveCurrentFlow ); const types = useTypesStore((state) => state.types); const templates = useTypesStore((state) => state.templates); const setFilterEdge = useFlowStore((state) => state.setFilterEdge); const reactFlowWrapper = useRef(null); const [showCanvas, setSHowCanvas] = useState( - Object.keys(templates).length > 0 && Object.keys(types).length > 0, + Object.keys(templates).length > 0 && Object.keys(types).length > 0 ); const reactFlowInstance = useFlowStore((state) => state.reactFlowInstance); const setReactFlowInstance = useFlowStore( - (state) => state.setReactFlowInstance, + (state) => state.setReactFlowInstance ); const nodes = useFlowStore((state) => state.nodes); const edges = useFlowStore((state) => state.edges); @@ -91,10 +91,10 @@ export default function Page({ const paste = useFlowStore((state) => state.paste); const resetFlow = useFlowStore((state) => state.resetFlow); const lastCopiedSelection = useFlowStore( - (state) => state.lastCopiedSelection, + (state) => state.lastCopiedSelection ); const setLastCopiedSelection = useFlowStore( - (state) => state.setLastCopiedSelection, + (state) => state.setLastCopiedSelection ); const onConnect = useFlowStore((state) => state.onConnect); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); @@ -117,7 +117,7 @@ export default function Page({ clonedSelection!, clonedNodes, clonedEdges, - getRandomName(), + getRandomName() ); const newGroupNode = generateNodeFromFlow(newFlow, getNodeId); const newEdges = reconnectEdges(newGroupNode, removedEdges); @@ -125,8 +125,8 @@ export default function Page({ ...clonedNodes.filter( (oldNodes) => !clonedSelection?.nodes.some( - (selectionNode) => selectionNode.id === oldNodes.id, - ), + (selectionNode) => selectionNode.id === oldNodes.id + ) ), newGroupNode, ]); @@ -136,8 +136,8 @@ export default function Page({ !clonedSelection!.nodes.some( (selectionNode) => selectionNode.id === oldEdge.target || - selectionNode.id === oldEdge.source, - ), + selectionNode.id === oldEdge.source + ) ), ...newEdges, ]); @@ -213,7 +213,7 @@ export default function Page({ { x: position.current.x, y: position.current.y, - }, + } ); } } @@ -297,7 +297,7 @@ export default function Page({ useEffect(() => { setSHowCanvas( - Object.keys(templates).length > 0 && Object.keys(types).length > 0, + Object.keys(templates).length > 0 && Object.keys(types).length > 0 ); }, [templates, types]); @@ -306,7 +306,7 @@ export default function Page({ takeSnapshot(); onConnect(params); }, - [takeSnapshot, onConnect], + [takeSnapshot, onConnect] ); const onNodeDragStart: NodeDragHandler = useCallback(() => { @@ -347,7 +347,7 @@ export default function Page({ // Extract the data from the drag event and parse it as a JSON object const data: { type: string; node?: APIClassType } = JSON.parse( - event.dataTransfer.getData("nodedata"), + event.dataTransfer.getData("nodedata") ); const newId = getNodeId(data.type); @@ -363,7 +363,7 @@ export default function Page({ }; paste( { nodes: [newNode], edges: [] }, - { x: event.clientX, y: event.clientY }, + { x: event.clientX, y: event.clientY } ); } else if (event.dataTransfer.types.some((types) => types === "Files")) { takeSnapshot(); @@ -392,7 +392,7 @@ export default function Page({ } }, // Specify dependencies for useCallback - [getNodeId, setNodes, takeSnapshot, paste], + [getNodeId, setNodes, takeSnapshot, paste] ); const onEdgeUpdateStart = useCallback(() => { @@ -408,7 +408,7 @@ export default function Page({ setEdges((els) => updateEdge(oldEdge, newConnection, els)); } }, - [setEdges], + [setEdges] ); const onEdgeUpdateEnd = useCallback((_, edge: Edge): void => { @@ -441,7 +441,7 @@ export default function Page({ (flow: OnSelectionChangeParams): void => { setLastSelection(flow); }, - [], + [] ); const onPaneClick = useCallback((flow) => { diff --git a/src/frontend/src/pages/FlowPage/components/PageComponent/utils/get-random-name.tsx b/src/frontend/src/pages/FlowPage/components/PageComponent/utils/get-random-name.tsx index d3bcf4d55..a58b83ec3 100644 --- a/src/frontend/src/pages/FlowPage/components/PageComponent/utils/get-random-name.tsx +++ b/src/frontend/src/pages/FlowPage/components/PageComponent/utils/get-random-name.tsx @@ -5,7 +5,7 @@ import { toTitleCase } from "../../../../../utils/utils"; export default function getRandomName( retry: number = 0, noSpace: boolean = false, - maxRetries: number = 3, + maxRetries: number = 3 ): string { const left: string[] = ADJECTIVES; const right: string[] = NOUNS; diff --git a/src/frontend/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx index 7b8193caa..8734d54f8 100644 --- a/src/frontend/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/SelectionMenuComponent/index.tsx @@ -13,7 +13,7 @@ export default function SelectionMenu({ const [disable, setDisable] = useState( lastSelection && edges.length > 0 ? validateSelection(lastSelection!, edges).length > 0 - : false, + : false ); const [isOpen, setIsOpen] = useState(false); const [isTransitioning, setIsTransitioning] = useState(false); diff --git a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx index 696f9898a..d193d2e6b 100644 --- a/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/extraSidebarComponent/index.tsx @@ -41,7 +41,7 @@ export default function ExtraSidebar(): JSX.Element { const [search, setSearch] = useState(""); function onDragStart( event: React.DragEvent, - data: { type: string; node?: APIClassType }, + data: { type: string; node?: APIClassType } ): void { //start drag event var crt = event.currentTarget.cloneNode(true); @@ -67,7 +67,7 @@ export default function ExtraSidebar(): JSX.Element { let keys = Object.keys(data[d]).filter( (nd) => nd.toLowerCase().includes(e.toLowerCase()) || - data[d][nd].display_name?.toLowerCase().includes(e.toLowerCase()), + data[d][nd].display_name?.toLowerCase().includes(e.toLowerCase()) ); keys.forEach((element) => { ret[d][element] = data[d][element]; @@ -134,7 +134,7 @@ export default function ExtraSidebar(): JSX.Element { if (filtered.some((x) => x !== "")) { let keys = Object.keys(dataClone[d]).filter((nd) => - filtered.includes(nd), + filtered.includes(nd) ); Object.keys(dataClone[d]).forEach((element) => { if (!keys.includes(element)) { @@ -171,7 +171,7 @@ export default function ExtraSidebar(): JSX.Element { if (filtered.some((x) => x !== "")) { let keys = Object.keys(dataClone[d]).filter((nd) => - filtered.includes(nd), + filtered.includes(nd) ); Object.keys(dataClone[d]).forEach((element) => { if (!keys.includes(element)) { @@ -200,7 +200,7 @@ export default function ExtraSidebar(): JSX.Element { "extra-side-bar-buttons gap-[4px] text-sm font-semibold", !hasApiKey || !validApiKey || !hasStore ? "button-disable cursor-default text-muted-foreground" - : "", + : "" )} > Share ), - [hasApiKey, validApiKey, currentFlow, hasStore], + [hasApiKey, validApiKey, currentFlow, hasStore] ); const ExportMemo = useMemo( @@ -227,7 +227,7 @@ export default function ExtraSidebar(): JSX.Element { ), - [], + [] ); const getIcon = useMemo(() => { @@ -311,8 +311,8 @@ export default function ExtraSidebar(): JSX.Element { .sort((a, b) => sensitiveSort( dataFilter[SBSectionName][a].display_name, - dataFilter[SBSectionName][b].display_name, - ), + dataFilter[SBSectionName][b].display_name + ) ) .map((SBItemName: string, index) => ( ) : (
    - ), + ) )}{" "} sensitiveSort( dataFilter[SBSectionName][a].display_name, - dataFilter[SBSectionName][b].display_name, - ), + dataFilter[SBSectionName][b].display_name + ) ) .map((SBItemName: string, index) => ( ) : (
    - ), + ) )}
    diff --git a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx index 8d217b2b2..bcf9e7018 100644 --- a/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/nodeToolbarComponent/index.tsx @@ -50,7 +50,7 @@ export default function NodeToolbarComponent({ const [showconfirmShare, setShowconfirmShare] = useState(false); const [showOverrideModal, setShowOverrideModal] = useState(false); const [flowComponent, setFlowComponent] = useState( - createFlowComponent(cloneDeep(data), version), + createFlowComponent(cloneDeep(data), version) ); const preventDefault = true; const isMac = navigator.platform.toUpperCase().includes("MAC"); @@ -67,7 +67,7 @@ export default function NodeToolbarComponent({ data.node.template[templateField]?.type === "Any" || data.node.template[templateField]?.type === "int" || data.node.template[templateField]?.type === "dict" || - data.node.template[templateField]?.type === "NestedDict"), + data.node.template[templateField]?.type === "NestedDict") ).length; const hasStore = useStoreStore((state) => state.hasStore); @@ -220,7 +220,7 @@ export default function NodeToolbarComponent({ const updateNodeInternals = useUpdateNodeInternals(); const setLastCopiedSelection = useFlowStore( - (state) => state.setLastCopiedSelection, + (state) => state.setLastCopiedSelection ); const setSuccessData = useAlertStore((state) => state.setSuccessData); @@ -294,7 +294,7 @@ export default function NodeToolbarComponent({ nodes, edges, setNodes, - setEdges, + setEdges ); break; case "override": @@ -321,14 +321,14 @@ export default function NodeToolbarComponent({ y: 10, paneX: nodes.find((node) => node.id === data.id)?.position.x, paneY: nodes.find((node) => node.id === data.id)?.position.y, - }, + } ); break; } }; const isSaved = flows.some((flow) => - Object.values(flow).includes(data.node?.display_name!), + Object.values(flow).includes(data.node?.display_name!) ); function displayShortcut({ @@ -346,7 +346,7 @@ export default function NodeToolbarComponent({ } }); const filteredShortcut = fixedShortcut.filter( - (key) => !key.toLowerCase().includes("shift"), + (key) => !key.toLowerCase().includes("shift") ); let shortcutWPlus: string[] = []; if (!hasShift) shortcutWPlus = filteredShortcut.join("+").split(" "); @@ -370,7 +370,7 @@ export default function NodeToolbarComponent({ const setNode = useFlowStore((state) => state.setNode); const handleOnNewValue = ( - newValue: string | string[] | boolean | Object[], + newValue: string | string[] | boolean | Object[] ): void => { if (data.node!.template[name].value !== newValue) { takeSnapshot(); @@ -426,8 +426,8 @@ export default function NodeToolbarComponent({ name.split(" ")[0].toLowerCase() === "code", - )!, + ({ name }) => name.split(" ")[0].toLowerCase() === "code" + )! )} side="top" > @@ -446,8 +446,8 @@ export default function NodeToolbarComponent({ name.split(" ")[0].toLowerCase() === "advanced", - )!, + ({ name }) => name.split(" ")[0].toLowerCase() === "advanced" + )! )} side="top" > @@ -486,14 +486,14 @@ export default function NodeToolbarComponent({ name.split(" ")[0].toLowerCase() === "freeze", - )!, + ({ name }) => name.split(" ")[0].toLowerCase() === "freeze" + )! )} side="top" > @@ -542,7 +542,7 @@ export default function NodeToolbarComponent({
    !key.toLowerCase().includes("shift"), + (key) => !key.toLowerCase().includes("shift") ); let shortcutWPlus: string[] = []; if (!hasShift) shortcutWPlus = filteredShortcut.join("+").split(" "); diff --git a/src/frontend/src/pages/FlowPage/index.tsx b/src/frontend/src/pages/FlowPage/index.tsx index 49fdb1eca..e5a67bd35 100644 --- a/src/frontend/src/pages/FlowPage/index.tsx +++ b/src/frontend/src/pages/FlowPage/index.tsx @@ -10,7 +10,7 @@ import ExtraSidebar from "./components/extraSidebarComponent"; export default function FlowPage({ view }: { view?: boolean }): JSX.Element { const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const version = useDarkStore((state) => state.version); const setOnFlowPage = useFlowStore((state) => state.setOnFlowPage); diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx index 395088193..af78db50d 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-delete-multiple.tsx @@ -9,7 +9,7 @@ const useDeleteMultipleFlows = ( myCollectionId, getFolderById, setSuccessData, - setErrorData, + setErrorData ) => { const handleDeleteMultiple = useCallback(() => { removeFlow(selectedFlowsComponentsCards) diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx index 96b1757ff..b391d9c8e 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-filtered-flows.tsx @@ -4,7 +4,7 @@ import { useEffect } from "react"; const useFilteredFlows = ( flowsFromFolder, searchFlowsComponents, - setAllFlows, + setAllFlows ) => { useEffect(() => { const newFlows = cloneDeep(flowsFromFolder || []); @@ -13,7 +13,7 @@ const useFilteredFlows = ( f.name.toLowerCase().includes(searchFlowsComponents.toLowerCase()) || f.description .toLowerCase() - .includes(searchFlowsComponents.toLowerCase()), + .includes(searchFlowsComponents.toLowerCase()) ); if (searchFlowsComponents === "") { diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx index fc49fc0d1..97e966b91 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-duplicate.tsx @@ -12,16 +12,16 @@ const useDuplicateFlows = ( setSuccessData, setSelectedFlowsComponentsCards, handleSelectAll, - cardTypes, + cardTypes ) => { const handleDuplicate = useCallback(() => { Promise.all( selectedFlowsComponentsCards.map((selectedFlow) => addFlow( true, - allFlows.find((flow) => flow.id === selectedFlow), - ), - ), + allFlows.find((flow) => flow.id === selectedFlow) + ) + ) ).then(() => { resetFilter(); getFoldersApi(true); diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx index bd742045b..446525f13 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-export.tsx @@ -9,7 +9,7 @@ const useExportFlows = ( setSuccessData, setSelectedFlowsComponentsCards, handleSelectAll, - cardTypes, + cardTypes ) => { const handleExport = useCallback(() => { selectedFlowsComponentsCards.forEach((selectedFlowId) => { @@ -25,7 +25,7 @@ const useExportFlows = ( is_component: false, }), selectedFlow.name, - selectedFlow.description, + selectedFlow.description ); } }); diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx index a81515e0a..5b20a4ddc 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-handle-select-all.tsx @@ -16,7 +16,7 @@ const useSelectAll = (flowsFromFolder, getValues, setValue) => { setValue(key, false); }); }, - [flowsFromFolder, getValues, setValue], + [flowsFromFolder, getValues, setValue] ); return { handleSelectAll }; diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx index 56dc204c7..b19ec4f4f 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-select-options-change.tsx @@ -5,7 +5,7 @@ const useSelectOptionsChange = ( setErrorData, setOpenDelete, handleDuplicate, - handleExport, + handleExport ) => { const handleSelectOptionsChange = useCallback( (action) => { @@ -31,7 +31,7 @@ const useSelectOptionsChange = ( setOpenDelete, handleDuplicate, handleExport, - ], + ] ); return { handleSelectOptionsChange }; diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx index b6f00934e..aa70b025f 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/hooks/use-selected-flows.tsx @@ -2,7 +2,7 @@ import { useEffect } from "react"; const useSelectedFlows = ( entireFormValues, - setSelectedFlowsComponentsCards, + setSelectedFlowsComponentsCards ) => { useEffect(() => { if (!entireFormValues || Object.keys(entireFormValues).length === 0) return; diff --git a/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx b/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx index af13e2bb4..81d2aa18d 100644 --- a/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/componentsComponent/index.tsx @@ -40,22 +40,22 @@ export default function ComponentsComponent({ const allFlows = useFlowsManagerStore((state) => state.allFlows); const flowsFromFolder = useFolderStore( - (state) => state.selectedFolder?.flows, + (state) => state.selectedFolder?.flows ); const setSuccessData = useAlertStore((state) => state.setSuccessData); const setErrorData = useAlertStore((state) => state.setErrorData); const [openDelete, setOpenDelete] = useState(false); const searchFlowsComponents = useFlowsManagerStore( - (state) => state.searchFlowsComponents, + (state) => state.searchFlowsComponents ); const setSelectedFlowsComponentsCards = useFlowsManagerStore( - (state) => state.setSelectedFlowsComponentsCards, + (state) => state.setSelectedFlowsComponentsCards ); const selectedFlowsComponentsCards = useFlowsManagerStore( - (state) => state.selectedFlowsComponentsCards, + (state) => state.selectedFlowsComponentsCards ); const [handleFileDrop] = useFileDrop(uploadFlow, type)!; @@ -109,7 +109,7 @@ export default function ComponentsComponent({ const { handleSelectAll } = useSelectAll( flowsFromFolder, getValues, - setValue, + setValue ); const { handleDuplicate } = useDuplicateFlows( @@ -124,7 +124,7 @@ export default function ComponentsComponent({ setSuccessData, setSelectedFlowsComponentsCards, handleSelectAll, - cardTypes, + cardTypes ); const version = useDarkStore((state) => state.version); @@ -138,7 +138,7 @@ export default function ComponentsComponent({ setSuccessData, setSelectedFlowsComponentsCards, handleSelectAll, - cardTypes, + cardTypes ); const { handleSelectOptionsChange } = useSelectOptionsChange( @@ -146,7 +146,7 @@ export default function ComponentsComponent({ setErrorData, setOpenDelete, handleDuplicate, - handleExport, + handleExport ); const { handleDeleteMultiple } = useDeleteMultipleFlows( @@ -158,21 +158,21 @@ export default function ComponentsComponent({ myCollectionId, getFolderById, setSuccessData, - setErrorData, + setErrorData ); useSelectedFlows(entireFormValues, setSelectedFlowsComponentsCards); const descriptionModal = useDescriptionModal( selectedFlowsComponentsCards, - type, + type ); const getTotalRowsCount = () => { if (type === "all") return allFlows?.length; return allFlows?.filter( - (f) => (f.is_component ?? false) === (type === "component"), + (f) => (f.is_component ?? false) === (type === "component") )?.length; }; diff --git a/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx b/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx index 151cdd902..26999fbd5 100644 --- a/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/headerComponent/index.tsx @@ -107,7 +107,7 @@ const HeaderComponent = ({ name="Trash2" className={cn( "h-5 w-5 text-primary transition-all", - disableFunctions ? "" : "hover:text-status-red", + disableFunctions ? "" : "hover:text-status-red" )} /> diff --git a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx index 2c1b9cd49..17916f05b 100644 --- a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/headerTabsSearchComponent/index.tsx @@ -20,7 +20,7 @@ const HeaderTabsSearchComponent = ({}: HeaderTabsSearchComponentProps) => { const [inputValue, setInputValue] = useState(""); const setSearchFlowsComponents = useFlowsManagerStore( - (state) => state.setSearchFlowsComponents, + (state) => state.setSearchFlowsComponents ); const handleDownloadFolder = () => { diff --git a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/inputSearchComponent/index.tsx b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/inputSearchComponent/index.tsx index 59809425e..8619cb2d5 100644 --- a/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/inputSearchComponent/index.tsx +++ b/src/frontend/src/pages/MainPage/components/myCollectionComponent/components/inputSearchComponent/index.tsx @@ -23,7 +23,7 @@ const InputSearchComponent = ({ const pagePath = window.location.pathname; const allFlows = useFlowsManagerStore((state) => state.allFlows); const searchFlowsComponents = useFlowsManagerStore( - (state) => state.searchFlowsComponents, + (state) => state.searchFlowsComponents ); const disableInputSearch = diff --git a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx index ce2b653a2..0daa61257 100644 --- a/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx +++ b/src/frontend/src/pages/MainPage/pages/mainPage/index.tsx @@ -16,7 +16,7 @@ import useDropdownOptions from "../../hooks/use-dropdown-options"; export default function HomePage(): JSX.Element { const uploadFlow = useFlowsManagerStore((state) => state.uploadFlow); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const location = useLocation(); diff --git a/src/frontend/src/pages/MainPage/services/index.ts b/src/frontend/src/pages/MainPage/services/index.ts index 3e1286d5e..fbfc34389 100644 --- a/src/frontend/src/pages/MainPage/services/index.ts +++ b/src/frontend/src/pages/MainPage/services/index.ts @@ -30,12 +30,12 @@ export async function addFolder(data: AddFolderType): Promise { export async function updateFolder( body: FolderType, - folderId: string, + folderId: string ): Promise { try { const response = await api.patch( `${BASE_URL_API}folders/${folderId}`, - body, + body ); return response?.data; } catch (error) { @@ -68,7 +68,7 @@ export async function downloadFlowsFromFolders(folderId: string): Promise<{ }> { try { const response = await api.get( - `${BASE_URL_API}folders/download/${folderId}`, + `${BASE_URL_API}folders/download/${folderId}` ); if (response?.status !== 200) { throw new Error(`HTTP error! status: ${response?.status}`); @@ -82,7 +82,7 @@ export async function downloadFlowsFromFolders(folderId: string): Promise<{ } export async function uploadFlowsFromFolders( - flows: FormData, + flows: FormData ): Promise { try { const response = await api.post(`${BASE_URL_API}folders/upload/`, flows); @@ -99,11 +99,11 @@ export async function uploadFlowsFromFolders( export async function moveFlowToFolder( flowId: string, - folderId: string, + folderId: string ): Promise { try { const response = await api.patch( - `${BASE_URL_API}folders/move_to_folder/${flowId}/${folderId}`, + `${BASE_URL_API}folders/move_to_folder/${flowId}/${folderId}` ); return response?.data; } catch (error) { diff --git a/src/frontend/src/pages/MainPage/utils/handle-download-folder.ts b/src/frontend/src/pages/MainPage/utils/handle-download-folder.ts index 6817622d0..d6a8e957c 100644 --- a/src/frontend/src/pages/MainPage/utils/handle-download-folder.ts +++ b/src/frontend/src/pages/MainPage/utils/handle-download-folder.ts @@ -11,7 +11,7 @@ export function handleDownloadFolderFn(folderId: string) { data.folder_description = folder?.description || ""; const jsonString = `data:text/json;chatset=utf-8,${encodeURIComponent( - JSON.stringify(data), + JSON.stringify(data) )}`; const link = document.createElement("a"); diff --git a/src/frontend/src/pages/Playground/index.tsx b/src/frontend/src/pages/Playground/index.tsx index 4ea3cc506..d26147df6 100644 --- a/src/frontend/src/pages/Playground/index.tsx +++ b/src/frontend/src/pages/Playground/index.tsx @@ -11,7 +11,7 @@ export default function PlaygroundPage() { const currentFlow = useFlowsManagerStore((state) => state.currentFlow); const getFlowById = useFlowsManagerStore((state) => state.getFlowById); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); const setCurrentFlow = useFlowsManagerStore((state) => state.setCurrentFlow); diff --git a/src/frontend/src/pages/ProfileSettingsPage/index.tsx b/src/frontend/src/pages/ProfileSettingsPage/index.tsx index 5cedc5841..c1635dc9e 100644 --- a/src/frontend/src/pages/ProfileSettingsPage/index.tsx +++ b/src/frontend/src/pages/ProfileSettingsPage/index.tsx @@ -24,11 +24,11 @@ import { gradients } from "../../utils/styleUtils"; import GradientChooserComponent from "../SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent"; export default function ProfileSettingsPage(): JSX.Element { const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const [inputState, setInputState] = useState( - CONTROL_PATCH_USER_STATE, + CONTROL_PATCH_USER_STATE ); // set null id diff --git a/src/frontend/src/pages/SettingsPage/index.tsx b/src/frontend/src/pages/SettingsPage/index.tsx index 2e8f49cfc..e6eb41b2f 100644 --- a/src/frontend/src/pages/SettingsPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/index.tsx @@ -8,7 +8,7 @@ import useFlowsManagerStore from "../../stores/flowsManagerStore"; export default function SettingsPage(): JSX.Element { const pathname = location.pathname; const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); useEffect(() => { setCurrentFlowId(""); diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx index 74d5dae99..01b4b7415 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/hooks/use-handle-delete-key.tsx @@ -10,7 +10,7 @@ const useDeleteApiKeys = ( selectedRows, resetFilter, setSuccessData, - setErrorData, + setErrorData ) => { const handleDeleteKey = () => { Promise.all(selectedRows.map((selectedRow) => deleteApiKey(selectedRow))) diff --git a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx index af5280f72..e5b224a58 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ApiKeysPage/index.tsx @@ -25,7 +25,7 @@ export default function ApiKeysPage() { userData, setLoadingKeys, keysList, - setUserId, + setUserId ); function resetFilter() { @@ -36,7 +36,7 @@ export default function ApiKeysPage() { selectedRows, resetFilter, setSuccessData, - setErrorData, + setErrorData ); const columnDefs = getColumnDefs(); diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/PasswordForm/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/PasswordForm/index.tsx index 28edb2f09..d99752e7b 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/PasswordForm/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/PasswordForm/index.tsx @@ -17,7 +17,7 @@ type PasswordFormComponentProps = { handlePatchPassword: ( password: string, cnfPassword: string, - handleInput: any, + handleInput: any ) => void; }; const PasswordFormComponent = ({ diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx index 988af6ea9..1948c9482 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/hooks/use-preload-images.tsx @@ -14,8 +14,8 @@ const usePreloadImages = (profilePictures, setImagesLoaded) => { img.src = src; img.onload = resolve; img.onerror = resolve; - }), - ), + }) + ) ); }; @@ -26,9 +26,9 @@ const usePreloadImages = (profilePictures, setImagesLoaded) => { Object.keys(profilePictures).flatMap((folder) => profilePictures[folder].map((path) => imageArray.push( - `${firstUrl}${BASE_URL_API}files/profile_pictures/${folder}/${path}`, - ), - ), + `${firstUrl}${BASE_URL_API}files/profile_pictures/${folder}/${path}` + ) + ) ); preloadImages(imageArray).then(() => { diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx index 408bd8ee1..edfe58a16 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/ProfilePictureForm/components/profilePictureChooserComponent/index.tsx @@ -58,7 +58,7 @@ export default function ProfilePictureChooserComponent({ key={idx} src={`${BACKEND_URL.slice( 0, - BACKEND_URL.length - 1, + BACKEND_URL.length - 1 )}${BASE_URL_API}files/profile_pictures/${ folder + "/" + path }`} diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/StoreApiKeyForm/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/StoreApiKeyForm/index.tsx index 5bc5ea38b..1fbf34024 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/StoreApiKeyForm/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/components/StoreApiKeyForm/index.tsx @@ -47,8 +47,8 @@ const StoreApiKeyFormComponent = ({ {(hasApiKey && !validApiKey ? INVALID_API_KEY : !hasApiKey - ? NO_API_KEY - : "") + INSERT_API_KEY} + ? NO_API_KEY + : "") + INSERT_API_KEY} diff --git a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx index 239103777..917d61714 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GeneralPage/index.tsx @@ -21,13 +21,13 @@ import StoreApiKeyFormComponent from "./components/StoreApiKeyForm"; export default function GeneralPage() { const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const { scrollId } = useParams(); const [inputState, setInputState] = useState( - CONTROL_PATCH_USER_STATE, + CONTROL_PATCH_USER_STATE ); const { autoLogin } = useContext(AuthContext); @@ -48,7 +48,7 @@ export default function GeneralPage() { const { handlePatchPassword } = usePatchPassword( userData, setSuccessData, - setErrorData, + setErrorData ); const { handleGetProfilePictures } = useGetProfilePictures(setErrorData); @@ -57,7 +57,7 @@ export default function GeneralPage() { setSuccessData, setErrorData, userData, - setUserData, + setUserData ); useScrollToElement(scrollId, setCurrentFlowId); @@ -67,7 +67,7 @@ export default function GeneralPage() { setErrorData, setHasApiKey, setValidApiKey, - setLoadingApiKey, + setLoadingApiKey ); function handleInput({ diff --git a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx index 6f0dac836..ba9c465d7 100644 --- a/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/GlobalVariablesPage/index.tsx @@ -14,13 +14,13 @@ import { useGlobalVariablesStore } from "../../../../stores/globalVariablesStore export default function GlobalVariablesPage() { const globalVariablesEntries = useGlobalVariablesStore( - (state) => state.globalVariablesEntries, + (state) => state.globalVariablesEntries ); const removeGlobalVariable = useGlobalVariablesStore( - (state) => state.removeGlobalVariable, + (state) => state.removeGlobalVariable ); const globalVariables = useGlobalVariablesStore( - (state) => state.globalVariables, + (state) => state.globalVariables ); const setErrorData = useAlertStore((state) => state.setErrorData); const getVariableId = useGlobalVariablesStore((state) => state.getVariableId); diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx index e2e49e815..894969f52 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/EditShortcutButton/index.tsx @@ -31,7 +31,7 @@ export default function EditShortcutButton({ ? defaultShortcuts.find( (s) => s.name.split(" ")[0].toLowerCase().toLowerCase() === - shortcut[0]?.split(" ")[0].toLowerCase(), + shortcut[0]?.split(" ")[0].toLowerCase() )?.shortcut : ""; const [key, setKey] = useState(null); @@ -50,7 +50,7 @@ export default function EditShortcutButton({ } const setUniqueShortcut = useShortcutsStore( - (state) => state.updateUniqueShortcut, + (state) => state.updateUniqueShortcut ); function editCombination(): void { @@ -74,7 +74,7 @@ export default function EditShortcutButton({ setShortcuts(newCombination); localStorage.setItem( "langflow-shortcuts", - JSON.stringify(newCombination), + JSON.stringify(newCombination) ); setKey(null); setOpen(false); @@ -116,7 +116,7 @@ export default function EditShortcutButton({ const keysArr = keys.split(" "); let hasNewKey = false; return keysArr.some( - (k) => k.toLowerCase().trim() === keyToCompare.toLowerCase().trim(), + (k) => k.toLowerCase().trim() === keyToCompare.toLowerCase().trim() ); } @@ -137,7 +137,7 @@ export default function EditShortcutButton({ if (checkForKeys(key, fixedKey)) return; } setKey((oldKey) => - getFixedCombination({ oldKey: oldKey!, key: fixedKey }), + getFixedCombination({ oldKey: oldKey!, key: fixedKey }) ); } diff --git a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx index 5e1228c7d..90e442897 100644 --- a/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/ShortcutsPage/index.tsx @@ -40,7 +40,7 @@ export default function ShortcutsPage() { const combinationToEdit = shortcuts.filter((s) => s.name === selectedRows[0]); const [open, setOpen] = useState(false); const updateUniqueShortcut = useShortcutsStore( - (state) => state.updateUniqueShortcut, + (state) => state.updateUniqueShortcut ); function handleRestore() { diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx index 584300fdf..537c579af 100644 --- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-patch-profile-picture.tsx @@ -9,7 +9,7 @@ const usePatchProfilePicture = ( setSuccessData, setErrorData, currentUserData, - setUserData, + setUserData ) => { const handlePatchProfilePicture = async (profile_picture) => { try { diff --git a/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx b/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx index cf5871a26..bdd105fef 100644 --- a/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/hooks/use-save-key.tsx @@ -11,7 +11,7 @@ const useSaveKey = ( setErrorData, setHasApiKey, setValidApiKey, - setLoadingApiKey, + setLoadingApiKey ) => { const { storeApiKey } = useContext(AuthContext); @@ -35,7 +35,7 @@ const useSaveKey = ( setHasApiKey(false); setValidApiKey(false); setLoadingApiKey(false); - }, + } ); } }; diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx index d7f4d5202..f4de52cbb 100644 --- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/hooks/use-remove-messages.tsx @@ -5,7 +5,7 @@ const useRemoveMessages = ( setSelectedRows, setSuccessData, setErrorData, - selectedRows, + selectedRows ) => { const deleteMessages = useMessagesStore((state) => state.removeMessages); diff --git a/src/frontend/src/pages/SettingsPage/pages/messagesPage/index.tsx b/src/frontend/src/pages/SettingsPage/pages/messagesPage/index.tsx index 8b6f2a0a0..5b1766d8c 100644 --- a/src/frontend/src/pages/SettingsPage/pages/messagesPage/index.tsx +++ b/src/frontend/src/pages/SettingsPage/pages/messagesPage/index.tsx @@ -26,7 +26,7 @@ export default function MessagesPage() { setSelectedRows, setSuccessData, setErrorData, - selectedRows, + selectedRows ); const { handleUpdate } = useUpdateMessage(setSuccessData, setErrorData); @@ -63,7 +63,7 @@ export default function MessagesPage() { overlayNoRowsTemplate="No data available" onSelectionChanged={(event: SelectionChangedEvent) => { setSelectedRows( - event.api.getSelectedRows().map((row) => row.index), + event.api.getSelectedRows().map((row) => row.index) ); }} rowSelection="multiple" diff --git a/src/frontend/src/pages/StorePage/index.tsx b/src/frontend/src/pages/StorePage/index.tsx index 718888c66..80b842db7 100644 --- a/src/frontend/src/pages/StorePage/index.tsx +++ b/src/frontend/src/pages/StorePage/index.tsx @@ -46,7 +46,7 @@ export default function StorePage(): JSX.Element { const setErrorData = useAlertStore((state) => state.setErrorData); const setCurrentFlowId = useFlowsManagerStore( - (state) => state.setCurrentFlowId, + (state) => state.setCurrentFlowId ); const currentFlowId = useFlowsManagerStore((state) => state.currentFlowId); const [loading, setLoading] = useState(true); @@ -143,7 +143,7 @@ export default function StorePage(): JSX.Element { setTotalRowsCount( filteredCategories?.length === 0 ? Number(res?.count ?? 0) - : res?.results?.length ?? 0, + : res?.results?.length ?? 0 ); } }) @@ -183,7 +183,7 @@ export default function StorePage(): JSX.Element { disabled={loading} className={cn( `${!validApiKey ? "animate-pulse border-error" : ""}`, - loading ? "cursor-not-allowed" : "", + loading ? "cursor-not-allowed" : "" )} variant="primary" onClick={() => { diff --git a/src/frontend/src/routes.tsx b/src/frontend/src/routes.tsx index a1997e510..5623f0871 100644 --- a/src/frontend/src/routes.tsx +++ b/src/frontend/src/routes.tsx @@ -11,25 +11,25 @@ import MessagesPage from "./pages/SettingsPage/pages/messagesPage"; const AdminPage = lazy(() => import("./pages/AdminPage")); const LoginAdminPage = lazy(() => import("./pages/AdminPage/LoginPage")); const ApiKeysPage = lazy( - () => import("./pages/SettingsPage/pages/ApiKeysPage"), + () => import("./pages/SettingsPage/pages/ApiKeysPage") ); const DeleteAccountPage = lazy(() => import("./pages/DeleteAccountPage")); const FlowPage = lazy(() => import("./pages/FlowPage")); const LoginPage = lazy(() => import("./pages/LoginPage")); const MyCollectionComponent = lazy( - () => import("./pages/MainPage/components/myCollectionComponent"), + () => import("./pages/MainPage/components/myCollectionComponent") ); const HomePage = lazy(() => import("./pages/MainPage/pages/mainPage")); const PlaygroundPage = lazy(() => import("./pages/Playground")); const SettingsPage = lazy(() => import("./pages/SettingsPage")); const GeneralPage = lazy( - () => import("./pages/SettingsPage/pages/GeneralPage"), + () => import("./pages/SettingsPage/pages/GeneralPage") ); const GlobalVariablesPage = lazy( - () => import("./pages/SettingsPage/pages/GlobalVariablesPage"), + () => import("./pages/SettingsPage/pages/GlobalVariablesPage") ); const ShortcutsPage = lazy( - () => import("./pages/SettingsPage/pages/ShortcutsPage"), + () => import("./pages/SettingsPage/pages/ShortcutsPage") ); const SignUp = lazy(() => import("./pages/SignUpPage")); const StorePage = lazy(() => import("./pages/StorePage")); diff --git a/src/frontend/src/stores/darkStore.ts b/src/frontend/src/stores/darkStore.ts index 8c9c10951..79f5518da 100644 --- a/src/frontend/src/stores/darkStore.ts +++ b/src/frontend/src/stores/darkStore.ts @@ -36,7 +36,7 @@ export const useDarkStore = create((set, get) => ({ window.localStorage.setItem("githubStars", res?.toString() ?? "0"); window.localStorage.setItem( "githubStarsLastUpdated", - new Date().toString(), + new Date().toString() ); set(() => ({ stars: res, lastUpdated: new Date() })); }); diff --git a/src/frontend/src/stores/flowStore.ts b/src/frontend/src/stores/flowStore.ts index 99aea0515..6d1c2ad5c 100644 --- a/src/frontend/src/stores/flowStore.ts +++ b/src/frontend/src/stores/flowStore.ts @@ -74,7 +74,7 @@ const useFlowStore = create((set, get) => ({ updateFlowPool: ( nodeId: string, data: VertexBuildTypeAPI | ChatOutputType | ChatInputType, - buildId?: string, + buildId?: string ) => { let newFlowPool = cloneDeep({ ...get().flowPool }); if (!newFlowPool[nodeId]) { @@ -167,7 +167,7 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( newChange, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } ); } }, @@ -183,7 +183,7 @@ const useFlowStore = create((set, get) => ({ flowsManager.autoSaveCurrentFlow( get().nodes, newChange, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } ); } }, @@ -201,7 +201,7 @@ const useFlowStore = create((set, get) => ({ return newChange; } return node; - }), + }) ); }, getNode: (id: string) => { @@ -212,8 +212,8 @@ const useFlowStore = create((set, get) => ({ get().nodes.filter((node) => typeof nodeId === "string" ? node.id !== nodeId - : !nodeId.includes(node.id), - ), + : !nodeId.includes(node.id) + ) ); }, deleteEdge: (edgeId) => { @@ -221,8 +221,8 @@ const useFlowStore = create((set, get) => ({ get().edges.filter((edge) => typeof edgeId === "string" ? edge.id !== edgeId - : !edgeId.includes(edge.id), - ), + : !edgeId.includes(edge.id) + ) ); }, paste: (selection, position) => { @@ -288,7 +288,7 @@ const useFlowStore = create((set, get) => ({ let source = idsMap[edge.source]; let target = idsMap[edge.target]; const sourceHandleObject: sourceHandleType = scapeJSONParse( - edge.sourceHandle!, + edge.sourceHandle! ); let sourceHandle = scapedJSONStringfy({ ...sourceHandleObject, @@ -298,7 +298,7 @@ const useFlowStore = create((set, get) => ({ edge.data.sourceHandle = sourceHandleObject; const targetHandleObject: targetHandleType = scapeJSONParse( - edge.targetHandle!, + edge.targetHandle! ); let targetHandle = scapedJSONStringfy({ ...targetHandleObject, @@ -317,7 +317,7 @@ const useFlowStore = create((set, get) => ({ data: cloneDeep(edge.data), selected: false, }, - newEdges.map((edge) => ({ ...edge, selected: false })), + newEdges.map((edge) => ({ ...edge, selected: false })) ); }); get().setEdges(newEdges); @@ -336,10 +336,10 @@ const useFlowStore = create((set, get) => ({ }); const newNodes = get().nodes.filter( - (node) => !nodesIdsSelected.includes(node.id), + (node) => !nodesIdsSelected.includes(node.id) ); const newEdges = get().edges.filter( - (edge) => !edgesIdsSelected.includes(edge.id), + (edge) => !edgesIdsSelected.includes(edge.id) ); set({ nodes: newNodes, edges: newEdges }); @@ -397,7 +397,7 @@ const useFlowStore = create((set, get) => ({ // style: { stroke: "#555" }, // className: "stroke-foreground stroke-connection", }, - oldEdges, + oldEdges ); return newEdges; @@ -407,7 +407,7 @@ const useFlowStore = create((set, get) => ({ .autoSaveCurrentFlow( get().nodes, newEdges, - get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 }, + get().reactFlowInstance?.getViewport() ?? { x: 0, y: 0, zoom: 1 } ); }, unselectAll: () => { @@ -442,7 +442,7 @@ const useFlowStore = create((set, get) => ({ function validateSubgraph(nodes: string[]) { const errorsObjs = validateNodes( get().nodes.filter((node) => nodes.includes(node.id)), - get().edges, + get().edges ); const errors = errorsObjs.map((obj) => obj.errors).flat(); @@ -461,13 +461,13 @@ const useFlowStore = create((set, get) => ({ function handleBuildUpdate( vertexBuildData: VertexBuildTypeAPI, status: BuildStatus, - runId: string, + runId: string ) { if (vertexBuildData && vertexBuildData.inactivated_vertices) { get().removeFromVerticesBuild(vertexBuildData.inactivated_vertices); get().updateBuildStatus( vertexBuildData.inactivated_vertices, - BuildStatus.INACTIVE, + BuildStatus.INACTIVE ); } @@ -483,14 +483,14 @@ const useFlowStore = create((set, get) => ({ // next_vertices_ids should be next_vertices_ids without the inactivated vertices const next_vertices_ids = vertexBuildData.next_vertices_ids.filter( - (id) => !vertexBuildData.inactivated_vertices?.includes(id), + (id) => !vertexBuildData.inactivated_vertices?.includes(id) ); const top_level_vertices = vertexBuildData.top_level_vertices.filter( - (vertex) => !vertexBuildData.inactivated_vertices?.includes(vertex), + (vertex) => !vertexBuildData.inactivated_vertices?.includes(vertex) ); const nextVertices: VertexLayerElementType[] = zip( next_vertices_ids, - top_level_vertices, + top_level_vertices ).map(([id, reference]) => ({ id: id!, reference })); const newLayers = [ @@ -512,7 +512,7 @@ const useFlowStore = create((set, get) => ({ get().addDataToFlowPool( { ...vertexBuildData, run_id: runId }, - vertexBuildData.id, + vertexBuildData.id ); useFlowStore.getState().updateBuildStatus([vertexBuildData.id], status); @@ -521,7 +521,7 @@ const useFlowStore = create((set, get) => ({ const newFlowBuildStatus = { ...get().flowBuildStatus }; // filter out the vertices that are not status const verticesToUpdate = verticesIds?.filter( - (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT, + (id) => newFlowBuildStatus[id]?.status !== BuildStatus.BUILT ); if (verticesToUpdate) { @@ -591,7 +591,7 @@ const useFlowStore = create((set, get) => ({ verticesLayers: VertexLayerElementType[][]; runId: string; verticesToRun: string[]; - } | null, + } | null ) => { set({ verticesBuild: vertices }); }, @@ -616,7 +616,7 @@ const useFlowStore = create((set, get) => ({ // that are going to be built verticesIds: get().verticesBuild!.verticesIds.filter( // keep the vertices that are not in the list of vertices to remove - (vertex) => !vertices.includes(vertex), + (vertex) => !vertices.includes(vertex) ), }, }); diff --git a/src/frontend/src/stores/flowsManagerStore.ts b/src/frontend/src/stores/flowsManagerStore.ts index 393681b72..d6bc8338e 100644 --- a/src/frontend/src/stores/flowsManagerStore.ts +++ b/src/frontend/src/stores/flowsManagerStore.ts @@ -87,12 +87,12 @@ const useFlowsManagerStore = create((set, get) => ({ if (dbData) { const { data, flows } = processFlows(dbData); const examples = flows.filter( - (flow) => flow.folder_id === starterFolderId, + (flow) => flow.folder_id === starterFolderId ); get().setExamples(examples); const flowsWithoutStarterFolder = flows.filter( - (flow) => flow.folder_id !== starterFolderId, + (flow) => flow.folder_id !== starterFolderId ); get().setFlows(flowsWithoutStarterFolder); @@ -120,7 +120,7 @@ const useFlowsManagerStore = create((set, get) => ({ if (get().currentFlow) { get().saveFlow( { ...get().currentFlow!, data: { nodes, edges, viewport } }, - true, + true ); } }, @@ -146,7 +146,7 @@ const useFlowsManagerStore = create((set, get) => ({ return updatedFlow; } return flow; - }), + }) ); //update tabs state @@ -195,7 +195,7 @@ const useFlowsManagerStore = create((set, get) => ({ flow?: FlowType, override?: boolean, position?: XYPosition, - fromDragAndDrop?: boolean, + fromDragAndDrop?: boolean ): Promise => { if (newProject) { let flowData = flow @@ -211,7 +211,7 @@ const useFlowsManagerStore = create((set, get) => ({ const newFlow = createNewFlow( flowData!, flow!, - folder_id || my_collection_id!, + folder_id || my_collection_id! ); const { id } = await saveFlowToDatabase(newFlow); newFlow.id = id; @@ -234,7 +234,7 @@ const useFlowsManagerStore = create((set, get) => ({ const newFlow = createNewFlow( flowData!, flow!, - folder_id || my_collection_id!, + folder_id || my_collection_id! ); const newName = addVersionToDuplicates(newFlow, get().flows); @@ -270,7 +270,7 @@ const useFlowsManagerStore = create((set, get) => ({ .getState() .paste( { nodes: flow!.data!.nodes, edges: flow!.data!.edges }, - position ?? { x: 10, y: 10 }, + position ?? { x: 10, y: 10 } ); } }, @@ -280,7 +280,7 @@ const useFlowsManagerStore = create((set, get) => ({ multipleDeleteFlowsComponents(id) .then(() => { const { data, flows } = processFlows( - get().flows.filter((flow) => !id.includes(flow.id)), + get().flows.filter((flow) => !id.includes(flow.id)) ); get().setFlows(flows); set({ isLoading: false }); @@ -300,7 +300,7 @@ const useFlowsManagerStore = create((set, get) => ({ deleteFlowFromDatabase(id) .then(() => { const { data, flows } = processFlows( - get().flows.filter((flow) => flow.id !== id), + get().flows.filter((flow) => flow.id !== id) ); get().setFlows(flows); set({ isLoading: false }); @@ -322,7 +322,7 @@ const useFlowsManagerStore = create((set, get) => ({ return new Promise((resolve) => { let componentFlow = get().flows.find( (componentFlow) => - componentFlow.is_component && componentFlow.name === key, + componentFlow.is_component && componentFlow.name === key ); if (componentFlow) { @@ -370,7 +370,7 @@ const useFlowsManagerStore = create((set, get) => ({ fileData, undefined, position, - true, + true ); resolve(id); } @@ -411,7 +411,7 @@ const useFlowsManagerStore = create((set, get) => ({ return get().addFlow( true, createFlowComponent(component, useDarkStore.getState().version), - override, + override ); }, takeSnapshot: () => { @@ -432,7 +432,7 @@ const useFlowsManagerStore = create((set, get) => ({ if (pastLength > 0) { past[currentFlowId] = past[currentFlowId].slice( pastLength - defaultOptions.maxHistorySize + 1, - pastLength, + pastLength ); past[currentFlowId].push(newState); diff --git a/src/frontend/src/stores/foldersStore.tsx b/src/frontend/src/stores/foldersStore.tsx index e72610987..25247ce76 100644 --- a/src/frontend/src/stores/foldersStore.tsx +++ b/src/frontend/src/stores/foldersStore.tsx @@ -17,18 +17,18 @@ export const useFolderStore = create((set, get) => ({ getFolders().then( (res) => { const foldersWithoutStarterProjects = res.filter( - (folder) => folder.name !== STARTER_FOLDER_NAME, + (folder) => folder.name !== STARTER_FOLDER_NAME ); const starterProjects = res.find( - (folder) => folder.name === STARTER_FOLDER_NAME, + (folder) => folder.name === STARTER_FOLDER_NAME ); set({ starterProjectId: starterProjects!.id ?? "" }); set({ folders: foldersWithoutStarterProjects }); const myCollectionId = res?.find( - (f) => f.name === DEFAULT_FOLDER, + (f) => f.name === DEFAULT_FOLDER )?.id; set({ myCollectionId }); @@ -45,7 +45,7 @@ export const useFolderStore = create((set, get) => ({ set({ folders: [] }); get().setLoading(false); reject(error); - }, + } ); } }); @@ -65,7 +65,7 @@ export const useFolderStore = create((set, get) => ({ }, () => { get().setLoadingById(false); - }, + } ); } }, diff --git a/src/frontend/src/stores/globalVariablesStore/globalVariables.ts b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts index 708f7ec09..c07813858 100644 --- a/src/frontend/src/stores/globalVariablesStore/globalVariables.ts +++ b/src/frontend/src/stores/globalVariablesStore/globalVariables.ts @@ -45,5 +45,5 @@ export const useGlobalVariablesStore = create( getVariableId: (name) => { return get().globalVariables[name]?.id; }, - }), + }) ); diff --git a/src/frontend/src/stores/messagesStore.ts b/src/frontend/src/stores/messagesStore.ts index 349a1c447..c6bf2042b 100644 --- a/src/frontend/src/stores/messagesStore.ts +++ b/src/frontend/src/stores/messagesStore.ts @@ -5,7 +5,7 @@ export const useMessagesStore = create((set, get) => ({ deleteSession: (id) => { set((state) => { const updatedMessages = state.messages.filter( - (msg) => msg.session_id !== id, + (msg) => msg.session_id !== id ); return { messages: updatedMessages }; }); @@ -29,7 +29,7 @@ export const useMessagesStore = create((set, get) => ({ updateMessage: (message) => { set(() => ({ messages: get().messages.map((msg) => - msg.index === message.index ? message : msg, + msg.index === message.index ? message : msg ), })); }, @@ -41,7 +41,7 @@ export const useMessagesStore = create((set, get) => ({ try { set((state) => { const updatedMessages = state.messages.filter( - (msg) => !ids.includes(msg.index), + (msg) => !ids.includes(msg.index) ); get().setMessages(updatedMessages); resolve(updatedMessages); diff --git a/src/frontend/src/types/components/index.ts b/src/frontend/src/types/components/index.ts index 99f890ebf..bb4b6d74e 100644 --- a/src/frontend/src/types/components/index.ts +++ b/src/frontend/src/types/components/index.ts @@ -492,7 +492,7 @@ export type ChatInputType = { isDragging: boolean; files: FilePreviewType[]; setFiles: ( - files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[]), + files: FilePreviewType[] | ((prev: FilePreviewType[]) => FilePreviewType[]) ) => void; chatValue: string; inputRef: { @@ -595,7 +595,7 @@ export type chatMessagePropsType = { updateChat: ( chat: ChatMessageType, message: string, - stream_url?: string, + stream_url?: string ) => void; }; @@ -687,12 +687,12 @@ export type codeTabsPropsType = { value: string, node: NodeType, template: TemplateVariableType, - tweak: tweakType, + tweak: tweakType ) => string; buildTweakObject?: ( tw: string, changes: string | string[] | boolean | number | Object[] | Object, - template: TemplateVariableType, + template: TemplateVariableType ) => Promise; }; activeTweaks?: boolean; diff --git a/src/frontend/src/types/store/index.ts b/src/frontend/src/types/store/index.ts index 54b7cb478..a3b26cb64 100644 --- a/src/frontend/src/types/store/index.ts +++ b/src/frontend/src/types/store/index.ts @@ -48,7 +48,7 @@ export type shortcutsStoreType = { shortcut: string; }>; setShortcuts: ( - newShortcuts: Array<{ name: string; shortcut: string }>, + newShortcuts: Array<{ name: string; shortcut: string }> ) => void; getShortcutsFromStorage: () => void; }; diff --git a/src/frontend/src/types/zustand/flow/index.ts b/src/frontend/src/types/zustand/flow/index.ts index 7449f7bc1..e8b88e8d3 100644 --- a/src/frontend/src/types/zustand/flow/index.ts +++ b/src/frontend/src/types/zustand/flow/index.ts @@ -86,7 +86,7 @@ export type FlowStoreType = { state: | FlowState | undefined - | ((oldState: FlowState | undefined) => FlowState), + | ((oldState: FlowState | undefined) => FlowState) ) => void; nodes: Node[]; edges: Edge[]; @@ -94,11 +94,11 @@ export type FlowStoreType = { onEdgesChange: OnEdgesChange; setNodes: ( update: Node[] | ((oldState: Node[]) => Node[]), - skipSave?: boolean, + skipSave?: boolean ) => void; setEdges: ( update: Edge[] | ((oldState: Edge[]) => Edge[]), - skipSave?: boolean, + skipSave?: boolean ) => void; setNode: (id: string, update: Node | ((oldState: Node) => Node)) => void; getNode: (id: string) => Node | undefined; @@ -106,12 +106,12 @@ export type FlowStoreType = { deleteEdge: (edgeId: string | Array) => void; paste: ( selection: { nodes: any; edges: any }, - position: { x: number; y: number; paneX?: number; paneY?: number }, + position: { x: number; y: number; paneX?: number; paneY?: number } ) => void; lastCopiedSelection: { nodes: any; edges: any } | null; setLastCopiedSelection: ( newSelection: { nodes: any; edges: any } | null, - isCrop?: boolean, + isCrop?: boolean ) => void; cleanFlow: () => void; setFilterEdge: (newState) => void; @@ -138,7 +138,7 @@ export type FlowStoreType = { verticesLayers: VertexLayerElementType[][]; runId: string; verticesToRun: string[]; - } | null, + } | null ) => void; addToVerticesBuild: (vertices: string[]) => void; removeFromVerticesBuild: (vertices: string[]) => void; @@ -156,7 +156,7 @@ export type FlowStoreType = { updateFlowPool: ( nodeId: string, data: VertexBuildTypeAPI | ChatOutputType | ChatInputType, - buildId?: string, + buildId?: string ) => void; getNodePosition: (nodeId: string) => { x: number; y: number }; }; diff --git a/src/frontend/src/types/zustand/flowsManager/index.ts b/src/frontend/src/types/zustand/flowsManager/index.ts index aaafebb7b..e0770626e 100644 --- a/src/frontend/src/types/zustand/flowsManager/index.ts +++ b/src/frontend/src/types/zustand/flowsManager/index.ts @@ -17,12 +17,12 @@ export type FlowsManagerStoreType = { saveFlow: (flow: FlowType, silent?: boolean) => Promise | undefined; saveFlowDebounce: ( flow: FlowType, - silent?: boolean, + silent?: boolean ) => Promise | undefined; autoSaveCurrentFlow: ( nodes: Node[], edges: Edge[], - viewport: Viewport, + viewport: Viewport ) => void; uploadFlows: () => Promise; uploadFlow: ({ @@ -41,13 +41,13 @@ export type FlowsManagerStoreType = { flow?: FlowType, override?: boolean, position?: XYPosition, - fromDragAndDrop?: boolean, + fromDragAndDrop?: boolean ) => Promise; deleteComponent: (key: string) => Promise; removeFlow: (id: string | string[]) => Promise; saveComponent: ( component: any, - override: boolean, + override: boolean ) => Promise; undo: () => void; redo: () => void; diff --git a/src/frontend/src/types/zustand/globalVariables/index.ts b/src/frontend/src/types/zustand/globalVariables/index.ts index 4b178088c..90817780f 100644 --- a/src/frontend/src/types/zustand/globalVariables/index.ts +++ b/src/frontend/src/types/zustand/globalVariables/index.ts @@ -21,7 +21,7 @@ export type GlobalVariablesStore = { id: string, type?: string, default_fields?: string[], - value?: string, + value?: string ) => void; removeGlobalVariable: (name: string) => Promise; getVariableId: (name: string) => string | undefined; diff --git a/src/frontend/src/utils/buildUtils.ts b/src/frontend/src/utils/buildUtils.ts index 5d70e1d12..4d0a3e147 100644 --- a/src/frontend/src/utils/buildUtils.ts +++ b/src/frontend/src/utils/buildUtils.ts @@ -17,7 +17,7 @@ type BuildVerticesParams = { onBuildUpdate?: ( data: VertexBuildTypeAPI, status: BuildStatus, - buildId: string, + buildId: string ) => void; // Replace any with the actual type if it's not any onBuildComplete?: (allNodesValid: boolean) => void; onBuildError?: (title, list, idList: VertexLayerElementType[]) => void; @@ -55,7 +55,7 @@ export async function updateVerticesOrder( startNodeId?: string | null, stopNodeId?: string | null, nodes?: Node[], - edges?: Edge[], + edges?: Edge[] ): Promise<{ verticesLayers: VertexLayerElementType[][]; verticesIds: string[]; @@ -71,7 +71,7 @@ export async function updateVerticesOrder( startNodeId, stopNodeId, nodes, - edges, + edges ); } catch (error: any) { setErrorData({ @@ -128,7 +128,7 @@ export async function buildVertices({ startNodeId, stopNodeId, nodes, - edges, + edges ); if (onValidateNodes) { try { @@ -190,14 +190,14 @@ export async function buildVertices({ onBuildUpdate( getInactiveVertexData(element.id), BuildStatus.INACTIVE, - runId, + runId ); } if (element.reference) { onBuildUpdate( getInactiveVertexData(element.reference), BuildStatus.INACTIVE, - runId, + runId ); } buildResults.push(false); @@ -223,7 +223,7 @@ export async function buildVertices({ if (stop) { return; } - }), + }) ); // Once the current layer is built, move to the next layer currentLayerIndex += 1; @@ -268,7 +268,7 @@ async function buildVertex({ onBuildError!( "Error Building Component", buildData.data.logs.map((log) => log.message), - verticesIds.map((id) => ({ id })), + verticesIds.map((id) => ({ id })) ); stopBuild(); } @@ -283,7 +283,7 @@ async function buildVertex({ (error as AxiosError).response?.data?.detail ?? "An unexpected error occurred while building the Component. Please try again.", ], - verticesIds.map((id) => ({ id })), + verticesIds.map((id) => ({ id })) ); stopBuild(); } diff --git a/src/frontend/src/utils/parameterUtils.ts b/src/frontend/src/utils/parameterUtils.ts index d1d53dde7..a1d2f2154 100644 --- a/src/frontend/src/utils/parameterUtils.ts +++ b/src/frontend/src/utils/parameterUtils.ts @@ -21,7 +21,7 @@ export const handleUpdateValues = async (name: string, data: NodeDataType) => { code, template, name, - data.node?.template[name]?.value, + data.node?.template[name]?.value ); if (res.status === 200 && data.node?.template) { return res.data.template; @@ -34,5 +34,5 @@ export const handleUpdateValues = async (name: string, data: NodeDataType) => { export const debouncedHandleUpdateValues = debounce( handleUpdateValues, - SAVE_DEBOUNCE_TIME, + SAVE_DEBOUNCE_TIME ); diff --git a/src/frontend/src/utils/storeUtils.ts b/src/frontend/src/utils/storeUtils.ts index c8391b211..637e4331a 100644 --- a/src/frontend/src/utils/storeUtils.ts +++ b/src/frontend/src/utils/storeUtils.ts @@ -7,7 +7,7 @@ export default function cloneFLowWithParent( flow: FlowType, parent: string, is_component: boolean, - keepId = false, + keepId = false ) { let childFLow = cloneDeep(flow); childFLow.parent = parent; diff --git a/src/frontend/src/utils/utils.ts b/src/frontend/src/utils/utils.ts index 302d9e0a7..5a1f6621f 100644 --- a/src/frontend/src/utils/utils.ts +++ b/src/frontend/src/utils/utils.ts @@ -56,7 +56,7 @@ export function normalCaseToSnakeCase(str: string): string { export function toTitleCase( str: string | undefined, - isNodeField?: boolean, + isNodeField?: boolean ): string { if (!str) return ""; let result = str @@ -65,7 +65,7 @@ export function toTitleCase( if (isNodeField) return word; if (index === 0) { return checkUpperWords( - word[0].toUpperCase() + word.slice(1).toLowerCase(), + word[0].toUpperCase() + word.slice(1).toLowerCase() ); } return checkUpperWords(word.toLowerCase()); @@ -78,7 +78,7 @@ export function toTitleCase( if (isNodeField) return word; if (index === 0) { return checkUpperWords( - word[0].toUpperCase() + word.slice(1).toLowerCase(), + word[0].toUpperCase() + word.slice(1).toLowerCase() ); } return checkUpperWords(word.toLowerCase()); @@ -182,7 +182,7 @@ export function checkLocalStorageKey(key: string): boolean { export function IncrementObjectKey( object: object, - key: string, + key: string ): { newKey: string; increment: number } { let count = 1; const type = removeCountFromString(key); @@ -217,7 +217,7 @@ export function groupByFamily( data: APIDataType, baseClasses: string, left: boolean, - flow?: NodeType[], + flow?: NodeType[] ): groupedObjType[] { const baseClassesSet = new Set(baseClasses.split("\n")); let arrOfPossibleInputs: Array<{ @@ -243,7 +243,7 @@ export function groupByFamily( baseClassesSet.has(template.type)) || (template?.input_types && template?.input_types.some((inputType) => - baseClassesSet.has(inputType), + baseClassesSet.has(inputType) ))) ); }; @@ -263,7 +263,7 @@ export function groupByFamily( hasBaseClassInBaseClasses: foundNode?.hasBaseClassInBaseClasses || nodeData.node!.base_classes.some((baseClass) => - baseClassesSet.has(baseClass), + baseClassesSet.has(baseClass) ), //seta como anterior ou verifica se o node tem base class displayName: nodeData.node?.display_name, }); @@ -280,10 +280,10 @@ export function groupByFamily( if (!foundNode) { foundNode = { hasBaseClassInTemplate: Object.values(node!.template).some( - checkBaseClass, + checkBaseClass ), hasBaseClassInBaseClasses: node!.base_classes.some((baseClass) => - baseClassesSet.has(baseClass), + baseClassesSet.has(baseClass) ), displayName: node?.display_name, }; @@ -355,7 +355,7 @@ export function isTimeStampString(str: string): boolean { export function extractColumnsFromRows( rows: object[], mode: "intersection" | "union", - excludeColumns?: Array, + excludeColumns?: Array ): (ColDef | ColGroupDef)[] { let columnsKeys: { [key: string]: ColDef | ColGroupDef } = {}; if (rows.length === 0) { diff --git a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts index c34c953ec..17cc25efb 100644 --- a/src/frontend/tests/end-to-end/chatInputOutput.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutput.spec.ts @@ -24,7 +24,7 @@ test("chat_io_teste", async ({ page }) => { const jsonContent = readFileSync( "src/frontend/tests/end-to-end/assets/ChatTest.json", - "utf-8", + "utf-8" ); await page.getByTestId("blank-flow").click(); @@ -62,7 +62,7 @@ test("chat_io_teste", async ({ page }) => { // Click and hold on the first element await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[10]/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[10]/button/div/div' ) .hover(); await page.mouse.down(); @@ -70,7 +70,7 @@ test("chat_io_teste", async ({ page }) => { // Move to the second element await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[4]/div/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[4]/div/button/div/div' ) .hover(); diff --git a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts index 6950ca230..89a066415 100644 --- a/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts +++ b/src/frontend/tests/end-to-end/chatInputOutputUser.spec.ts @@ -56,7 +56,7 @@ test("user must interact with chat with Input/Output", async ({ page }) => { .getByTestId("textarea-input_value") .nth(1) .fill( - "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", + "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!" ); await page.getByText("Playground", { exact: true }).last().click(); await page.getByTestId("icon-LucideSend").click(); @@ -92,9 +92,9 @@ test("user must interact with chat with Input/Output", async ({ page }) => { await page .getByText( "testtesttesttesttesttestte;.;.,;,.;,.;.,;,..,;;;;;;;;;;;;;;;;;;;;;,;.;,.;,.,;.,;.;.,~~çççççççççççççççççççççççççççççççççççççççisdajfdasiopjfaodisjhvoicxjiovjcxizopjviopasjioasfhjaiohf23432432432423423sttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttesttestççççççççççççççççççççççççççççççççç,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,.,!", - { exact: true }, + { exact: true } ) - .isVisible(), + .isVisible() ); }); @@ -204,7 +204,7 @@ test("user must be able to send an image on chat", async ({ page }) => { const jsonContent = readFileSync( "src/frontend/tests/end-to-end/assets/chain.png", - "utf-8", + "utf-8" ); // Create the DataTransfer and File diff --git a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts index 03d11aaf7..3e760901d 100644 --- a/src/frontend/tests/end-to-end/dragAndDrop.spec.ts +++ b/src/frontend/tests/end-to-end/dragAndDrop.spec.ts @@ -27,7 +27,7 @@ test.describe("drag and drop test", () => { // Read your file into a buffer. const jsonContent = readFileSync( "src/frontend/tests/end-to-end/assets/collection.json", - "utf-8", + "utf-8" ); // Create the DataTransfer and File @@ -47,7 +47,7 @@ test.describe("drag and drop test", () => { "drop", { dataTransfer, - }, + } ); const genericNoda = page.getByTestId("div-generic-node"); diff --git a/src/frontend/tests/end-to-end/dropdownComponent.spec.ts b/src/frontend/tests/end-to-end/dropdownComponent.spec.ts index 6c0a7dd9e..0152ca7ed 100644 --- a/src/frontend/tests/end-to-end/dropdownComponent.spec.ts +++ b/src/frontend/tests/end-to-end/dropdownComponent.spec.ts @@ -80,32 +80,32 @@ test("dropDownComponent", async ({ page }) => { await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showendpoint_url"]').click(); expect( - await page.locator('//*[@id="showendpoint_url"]').isChecked(), + await page.locator('//*[@id="showendpoint_url"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showendpoint_url"]').click(); expect( - await page.locator('//*[@id="showendpoint_url"]').isChecked(), + await page.locator('//*[@id="showendpoint_url"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showregion_name"]').click(); expect( - await page.locator('//*[@id="showregion_name"]').isChecked(), + await page.locator('//*[@id="showregion_name"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showregion_name"]').click(); expect( - await page.locator('//*[@id="showregion_name"]').isChecked(), + await page.locator('//*[@id="showregion_name"]').isChecked() ).toBeTruthy(); // showmodel_id @@ -115,7 +115,7 @@ test("dropDownComponent", async ({ page }) => { // showmodel_id await page.locator('//*[@id="showmodel_id"]').click(); expect( - await page.locator('//*[@id="showmodel_id"]').isChecked(), + await page.locator('//*[@id="showmodel_id"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showcache"]').click(); @@ -126,32 +126,32 @@ test("dropDownComponent", async ({ page }) => { await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showendpoint_url"]').click(); expect( - await page.locator('//*[@id="showendpoint_url"]').isChecked(), + await page.locator('//*[@id="showendpoint_url"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showendpoint_url"]').click(); expect( - await page.locator('//*[@id="showendpoint_url"]').isChecked(), + await page.locator('//*[@id="showendpoint_url"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showregion_name"]').click(); expect( - await page.locator('//*[@id="showregion_name"]').isChecked(), + await page.locator('//*[@id="showregion_name"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showregion_name"]').click(); expect( - await page.locator('//*[@id="showregion_name"]').isChecked(), + await page.locator('//*[@id="showregion_name"]').isChecked() ).toBeTruthy(); // showmodel_id @@ -161,7 +161,7 @@ test("dropDownComponent", async ({ page }) => { // showmodel_id await page.locator('//*[@id="showmodel_id"]').click(); expect( - await page.locator('//*[@id="showmodel_id"]').isChecked(), + await page.locator('//*[@id="showmodel_id"]').isChecked() ).toBeTruthy(); await page.getByTestId("dropdown-edit-model_id").click(); diff --git a/src/frontend/tests/end-to-end/fileUploadComponent.spec.ts b/src/frontend/tests/end-to-end/fileUploadComponent.spec.ts index 00f761dea..93b471c43 100644 --- a/src/frontend/tests/end-to-end/fileUploadComponent.spec.ts +++ b/src/frontend/tests/end-to-end/fileUploadComponent.spec.ts @@ -64,7 +64,7 @@ test("dropDownComponent", async ({ page }) => { // Click and hold on the first element await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[6]/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[1]/div/div[2]/div[6]/button/div/div' ) .hover(); await page.mouse.down(); @@ -72,7 +72,7 @@ test("dropDownComponent", async ({ page }) => { // Move to the second element await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div[2]/div/div[2]/div[3]/div/button/div/div' ) .hover(); diff --git a/src/frontend/tests/end-to-end/filterEdge.spec.ts b/src/frontend/tests/end-to-end/filterEdge.spec.ts index 7edbc0436..9cb5a567e 100644 --- a/src/frontend/tests/end-to-end/filterEdge.spec.ts +++ b/src/frontend/tests/end-to-end/filterEdge.spec.ts @@ -40,7 +40,7 @@ test("LLMChain - Tooltip", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[3]/div/button/div/div', + '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[3]/div/button/div/div' ) .hover() .then(async () => { @@ -60,17 +60,17 @@ test("LLMChain - Tooltip", async ({ page }) => { await page.getByTitle("zoom out").click(); await page .locator( - '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[4]/div/button/div/div', + '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[4]/div/button/div/div' ) .hover() .then(async () => { await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("tooltip-Model Specs").first() ).toBeVisible(); await page.waitForTimeout(2000); await expect( - page.getByTestId("tooltip-Model Specs").first(), + page.getByTestId("tooltip-Model Specs").first() ).toBeVisible(); await page.getByTestId("icon-Search").click(); @@ -81,12 +81,12 @@ test("LLMChain - Tooltip", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[5]/div/button/div/div', + '//*[@id="react-flow-id"]/div[1]/div[1]/div/div/div[2]/div/div/div[2]/div[5]/div/button/div/div' ) .hover() .then(async () => { await expect( - page.getByTestId("empty-tooltip-filter").first(), + page.getByTestId("empty-tooltip-filter").first() ).toBeVisible(); }); }); @@ -113,7 +113,7 @@ test("LLMChain - Filter", async ({ page }) => { await page.waitForTimeout(1000); await page.getByTestId( - "input-list-plus-btn-edit_metadata_indexing_include-2", + "input-list-plus-btn-edit_metadata_indexing_include-2" ); await page.getByTestId("blank-flow").click(); @@ -136,7 +136,7 @@ test("LLMChain - Filter", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[4]/div/button/div/div' ) .click(); @@ -149,14 +149,14 @@ test("LLMChain - Filter", async ({ page }) => { await expect(page.getByTestId("model_specsChatOpenAI")).toBeVisible(); await expect(page.getByTestId("model_specsChatVertexAI")).toBeVisible(); await expect( - page.getByTestId("model_specsGoogle Generative AI"), + page.getByTestId("model_specsGoogle Generative AI") ).toBeVisible(); await expect( - page.getByTestId("model_specsHugging Face Inference API"), + page.getByTestId("model_specsHugging Face Inference API") ).toBeVisible(); await expect(page.getByTestId("model_specsOllama")).toBeVisible(); await expect( - page.getByTestId("model_specsQianfanChatEndpoint"), + page.getByTestId("model_specsQianfanChatEndpoint") ).toBeVisible(); await expect(page.getByTestId("model_specsQianfanLLMEndpoint")).toBeVisible(); await expect(page.getByTestId("model_specsVertexAI")).toBeVisible(); @@ -168,7 +168,7 @@ test("LLMChain - Filter", async ({ page }) => { await expect(page.getByTestId("model_specsAmazon Bedrock")).not.toBeVisible(); await expect(page.getByTestId("modelsAzure OpenAI")).not.toBeVisible(); await expect( - page.getByTestId("model_specsAzureChatOpenAI"), + page.getByTestId("model_specsAzureChatOpenAI") ).not.toBeVisible(); await expect(page.getByTestId("model_specsChatAnthropic")).not.toBeVisible(); await expect(page.getByTestId("model_specsChatLiteLLM")).not.toBeVisible(); @@ -178,13 +178,13 @@ test("LLMChain - Filter", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div' ) .click(); await page .locator( - '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div', + '//*[@id="react-flow-id"]/div/div[1]/div[1]/div/div[2]/div/div/div[2]/div[7]/button/div/div' ) .click(); diff --git a/src/frontend/tests/end-to-end/floatComponent.spec.ts b/src/frontend/tests/end-to-end/floatComponent.spec.ts index e172a92e3..0577a62b4 100644 --- a/src/frontend/tests/end-to-end/floatComponent.spec.ts +++ b/src/frontend/tests/end-to-end/floatComponent.spec.ts @@ -71,27 +71,27 @@ test("FloatComponent", async ({ page }) => { await page.getByTestId("showmirostat").click(); expect( - await page.locator('//*[@id="showmirostat"]').isChecked(), + await page.locator('//*[@id="showmirostat"]').isChecked() ).toBeTruthy(); await page.getByTestId("showmirostat_eta").click(); expect( - await page.locator('//*[@id="showmirostat_eta"]').isChecked(), + await page.locator('//*[@id="showmirostat_eta"]').isChecked() ).toBeTruthy(); await page.getByTestId("showmirostat_eta").click(); expect( - await page.locator('//*[@id="showmirostat_eta"]').isChecked(), + await page.locator('//*[@id="showmirostat_eta"]').isChecked() ).toBeFalsy(); await page.getByTestId("showmirostat_tau").click(); expect( - await page.locator('//*[@id="showmirostat_tau"]').isChecked(), + await page.locator('//*[@id="showmirostat_tau"]').isChecked() ).toBeTruthy(); await page.getByTestId("showmirostat_tau").click(); expect( - await page.locator('//*[@id="showmirostat_tau"]').isChecked(), + await page.locator('//*[@id="showmirostat_tau"]').isChecked() ).toBeFalsy(); await page.getByTestId("showmodel").click(); @@ -114,22 +114,22 @@ test("FloatComponent", async ({ page }) => { await page.getByTestId("shownum_thread").click(); expect( - await page.locator('//*[@id="shownum_thread"]').isChecked(), + await page.locator('//*[@id="shownum_thread"]').isChecked() ).toBeTruthy(); await page.getByTestId("shownum_thread").click(); expect( - await page.locator('//*[@id="shownum_thread"]').isChecked(), + await page.locator('//*[@id="shownum_thread"]').isChecked() ).toBeFalsy(); await page.getByTestId("showrepeat_last_n").click(); expect( - await page.locator('//*[@id="showrepeat_last_n"]').isChecked(), + await page.locator('//*[@id="showrepeat_last_n"]').isChecked() ).toBeTruthy(); await page.getByTestId("showrepeat_last_n").click(); expect( - await page.locator('//*[@id="showrepeat_last_n"]').isChecked(), + await page.locator('//*[@id="showrepeat_last_n"]').isChecked() ).toBeFalsy(); await page.getByText("Save Changes", { exact: true }).click(); @@ -145,7 +145,7 @@ test("FloatComponent", async ({ page }) => { // showtemperature await page.locator('//*[@id="showtemperature"]').click(); expect( - await page.locator('//*[@id="showtemperature"]').isChecked(), + await page.locator('//*[@id="showtemperature"]').isChecked() ).toBeTruthy(); await page.getByText("Save Changes", { exact: true }).click(); diff --git a/src/frontend/tests/end-to-end/flowSettings.spec.ts b/src/frontend/tests/end-to-end/flowSettings.spec.ts index 25807ed88..a2e9f25c0 100644 --- a/src/frontend/tests/end-to-end/flowSettings.spec.ts +++ b/src/frontend/tests/end-to-end/flowSettings.spec.ts @@ -29,7 +29,7 @@ test("flowSettings", async ({ page }) => { await page .getByPlaceholder("Flow name") .fill( - "Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test", + "Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test" ); await page.getByText("Character limit reached").isVisible(); @@ -41,7 +41,7 @@ test("flowSettings", async ({ page }) => { await page .getByPlaceholder("Flow description") .fill( - "Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test", + "Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test Flow Name Test" ); await page.getByTestId("save-flow-settings").click(); diff --git a/src/frontend/tests/end-to-end/folders.spec.ts b/src/frontend/tests/end-to-end/folders.spec.ts index e0f694910..384816b3f 100644 --- a/src/frontend/tests/end-to-end/folders.spec.ts +++ b/src/frontend/tests/end-to-end/folders.spec.ts @@ -58,7 +58,7 @@ test("add folder by drag and drop", async ({ page }) => { const jsonContent = readFileSync( "src/frontend/tests/end-to-end/assets/collection.json", - "utf-8", + "utf-8" ); // Create the DataTransfer and File @@ -78,7 +78,7 @@ test("add folder by drag and drop", async ({ page }) => { "drop", { dataTransfer, - }, + } ); await page.getByText("Getting Started").first().isVisible(); diff --git a/src/frontend/tests/end-to-end/inputComponent.spec.ts b/src/frontend/tests/end-to-end/inputComponent.spec.ts index 3e6936b43..d944cffe5 100644 --- a/src/frontend/tests/end-to-end/inputComponent.spec.ts +++ b/src/frontend/tests/end-to-end/inputComponent.spec.ts @@ -60,69 +60,69 @@ test("InputComponent", async ({ page }) => { expect( await page .locator('//*[@id="showchroma_server_cors_allow_origins"]') - .isChecked(), + .isChecked() ).toBeTruthy(); await page.locator('//*[@id="showchroma_server_grpc_port"]').click(); expect( - await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked(), + await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showchroma_server_host"]').click(); expect( - await page.locator('//*[@id="showchroma_server_host"]').isChecked(), + await page.locator('//*[@id="showchroma_server_host"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showchroma_server_http_port"]').click(); expect( - await page.locator('//*[@id="showchroma_server_http_port"]').isChecked(), + await page.locator('//*[@id="showchroma_server_http_port"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showchroma_server_ssl_enabled"]').click(); expect( - await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(), + await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showcollection_name"]').click(); expect( - await page.locator('//*[@id="showcollection_name"]').isChecked(), + await page.locator('//*[@id="showcollection_name"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showindex_directory"]').click(); expect( - await page.locator('//*[@id="showindex_directory"]').isChecked(), + await page.locator('//*[@id="showindex_directory"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showchroma_server_cors_allow_origins"]').click(); expect( await page .locator('//*[@id="showchroma_server_cors_allow_origins"]') - .isChecked(), + .isChecked() ).toBeFalsy(); await page.locator('//*[@id="showchroma_server_grpc_port"]').click(); expect( - await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked(), + await page.locator('//*[@id="showchroma_server_grpc_port"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showchroma_server_host"]').click(); expect( - await page.locator('//*[@id="showchroma_server_host"]').isChecked(), + await page.locator('//*[@id="showchroma_server_host"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showchroma_server_http_port"]').click(); expect( - await page.locator('//*[@id="showchroma_server_http_port"]').isChecked(), + await page.locator('//*[@id="showchroma_server_http_port"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showchroma_server_ssl_enabled"]').click(); expect( - await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked(), + await page.locator('//*[@id="showchroma_server_ssl_enabled"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showindex_directory"]').click(); expect( - await page.locator('//*[@id="showindex_directory"]').isChecked(), + await page.locator('//*[@id="showindex_directory"]').isChecked() ).toBeTruthy(); let valueEditNode = await page @@ -152,7 +152,7 @@ test("InputComponent", async ({ page }) => { await page.locator('//*[@id="showcollection_name"]').click(); expect( - await page.locator('//*[@id="showcollection_name"]').isChecked(), + await page.locator('//*[@id="showcollection_name"]').isChecked() ).toBeTruthy(); await page.getByText("Save Changes", { exact: true }).click(); diff --git a/src/frontend/tests/end-to-end/inputListComponent.spec.ts b/src/frontend/tests/end-to-end/inputListComponent.spec.ts index 74c527892..6414c92db 100644 --- a/src/frontend/tests/end-to-end/inputListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/inputListComponent.spec.ts @@ -41,19 +41,19 @@ test("InputListComponent", async ({ page }) => { await page.getByTestId("edit-button-modal").click(); expect( - await page.getByTestId("showmetadata_indexing_exclude").isChecked(), + await page.getByTestId("showmetadata_indexing_exclude").isChecked() ).toBeFalsy(); await page.getByTestId("showmetadata_indexing_exclude").click(); expect( - await page.getByTestId("showmetadata_indexing_exclude").isChecked(), + await page.getByTestId("showmetadata_indexing_exclude").isChecked() ).toBeTruthy(); expect( - await page.getByTestId("showmetadata_indexing_include").isChecked(), + await page.getByTestId("showmetadata_indexing_include").isChecked() ).toBeFalsy(); await page.getByTestId("showmetadata_indexing_include").click(); expect( - await page.getByTestId("showmetadata_indexing_include").isChecked(), + await page.getByTestId("showmetadata_indexing_include").isChecked() ).toBeTruthy(); await page @@ -93,7 +93,7 @@ test("InputListComponent", async ({ page }) => { .click(); const plusButtonLocator = page.getByTestId( - "input-list-plus-btn_metadata_indexing_include-1", + "input-list-plus-btn_metadata_indexing_include-1" ); const elementCount = await plusButtonLocator?.count(); @@ -164,12 +164,12 @@ test("InputListComponent", async ({ page }) => { .click(); const plusButtonLocatorEdit0 = await page.getByTestId( - "input-list-plus-btn-edit_metadata_indexing_include-0", + "input-list-plus-btn-edit_metadata_indexing_include-0" ); const elementCountEdit0 = await plusButtonLocatorEdit0?.count(); const plusButtonLocatorEdit2 = await page.getByTestId( - "input-list-plus-btn-edit_metadata_indexing_include-2", + "input-list-plus-btn-edit_metadata_indexing_include-2" ); const elementCountEdit2 = await plusButtonLocatorEdit2?.count(); @@ -178,13 +178,13 @@ test("InputListComponent", async ({ page }) => { } const minusButtonLocatorEdit1 = await page.getByTestId( - "input-list-minus-btn-edit_metadata_indexing_include-1", + "input-list-minus-btn-edit_metadata_indexing_include-1" ); const elementCountMinusEdit1 = await minusButtonLocatorEdit1?.count(); const minusButtonLocatorEdit2 = await page.getByTestId( - "input-list-minus-btn-edit_metadata_indexing_include-2", + "input-list-minus-btn-edit_metadata_indexing_include-2" ); const elementCountMinusEdit2 = await minusButtonLocatorEdit2?.count(); diff --git a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts index 31a4521ae..165dd685b 100644 --- a/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts +++ b/src/frontend/tests/end-to-end/keyPairListComponent.spec.ts @@ -81,7 +81,7 @@ test("KeypairListComponent", async ({ page }) => { expect(await page.locator('//*[@id="showcache"]').isChecked()).toBeFalsy(); await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeFalsy(); await page.getByText("Save Changes", { exact: true }).click(); @@ -96,7 +96,7 @@ test("KeypairListComponent", async ({ page }) => { await page.locator('//*[@id="showcredentials_profile_name"]').click(); expect( - await page.locator('//*[@id="showcredentials_profile_name"]').isChecked(), + await page.locator('//*[@id="showcredentials_profile_name"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showcache"]').click(); expect(await page.locator('//*[@id="showcache"]').isChecked()).toBeTruthy(); diff --git a/src/frontend/tests/end-to-end/langflowShortcuts.spec.ts b/src/frontend/tests/end-to-end/langflowShortcuts.spec.ts index 42b8744d1..58615dd55 100644 --- a/src/frontend/tests/end-to-end/langflowShortcuts.spec.ts +++ b/src/frontend/tests/end-to-end/langflowShortcuts.spec.ts @@ -61,7 +61,7 @@ test("LangflowShortcuts", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]', + '//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]' ) .click(); await page.keyboard.press("Backspace"); @@ -84,7 +84,7 @@ test("LangflowShortcuts", async ({ page }) => { await page .locator( - '//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]', + '//*[@id="react-flow-id"]/div[1]/div[1]/div[1]/div/div[2]/div[2]/div/div[1]/div/div[1]/div/div/div[1]' ) .click(); await page.keyboard.press("Backspace"); diff --git a/src/frontend/tests/end-to-end/nestedComponent.spec.ts b/src/frontend/tests/end-to-end/nestedComponent.spec.ts index 2df9c1b7b..3cd319576 100644 --- a/src/frontend/tests/end-to-end/nestedComponent.spec.ts +++ b/src/frontend/tests/end-to-end/nestedComponent.spec.ts @@ -41,7 +41,7 @@ test("NestedComponent", async ({ page }) => { await page.locator('//*[@id="showpool_threads"]').click(); expect( - await page.locator('//*[@id="showpool_threads"]').isChecked(), + await page.locator('//*[@id="showpool_threads"]').isChecked() ).toBeTruthy(); //showtext_key @@ -53,140 +53,140 @@ test("NestedComponent", async ({ page }) => { await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeFalsy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeFalsy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeFalsy(); // showindex_name await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeTruthy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeTruthy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeTruthy(); // showindex_name await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeFalsy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeFalsy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeFalsy(); // showindex_name await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeTruthy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeTruthy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeTruthy(); // showindex_name await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeFalsy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeFalsy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeFalsy(); // showindex_name await page.locator('//*[@id="showindex_name"]').click(); expect( - await page.locator('//*[@id="showindex_name"]').isChecked(), + await page.locator('//*[@id="showindex_name"]').isChecked() ).toBeTruthy(); // shownamespace await page.locator('//*[@id="shownamespace"]').click(); expect( - await page.locator('//*[@id="shownamespace"]').isChecked(), + await page.locator('//*[@id="shownamespace"]').isChecked() ).toBeTruthy(); // showpinecone_api_key await page.locator('//*[@id="showpinecone_api_key"]').click(); expect( - await page.locator('//*[@id="showpinecone_api_key"]').isChecked(), + await page.locator('//*[@id="showpinecone_api_key"]').isChecked() ).toBeTruthy(); //showpool_threads await page.locator('//*[@id="showpool_threads"]').click(); expect( - await page.locator('//*[@id="showpool_threads"]').isChecked(), + await page.locator('//*[@id="showpool_threads"]').isChecked() ).toBeFalsy(); //showtext_key await page.locator('//*[@id="showtext_key"]').click(); expect( - await page.locator('//*[@id="showtext_key"]').isChecked(), + await page.locator('//*[@id="showtext_key"]').isChecked() ).toBeTruthy(); await page.getByText("Save Changes", { exact: true }).click(); diff --git a/src/frontend/tests/end-to-end/store.spec.ts b/src/frontend/tests/end-to-end/store.spec.ts index 8e443ecdd..13963d698 100644 --- a/src/frontend/tests/end-to-end/store.spec.ts +++ b/src/frontend/tests/end-to-end/store.spec.ts @@ -262,7 +262,7 @@ test("should share component with share button", async ({ page }) => { await page.getByText("Set workflow status to public").isVisible(); await page .getByText( - "Attention: API keys in specified fields are automatically removed upon sharing.", + "Attention: API keys in specified fields are automatically removed upon sharing." ) .isVisible(); await page.getByText("Export").first().isVisible(); diff --git a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts index 9443586e6..fa4248a63 100644 --- a/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts +++ b/src/frontend/tests/end-to-end/textAreaModalComponent.spec.ts @@ -51,7 +51,7 @@ test("TextAreaModalComponent", async ({ page }) => { await page .getByTestId("textarea-text") .fill( - "test test test test test test test test test test test !@#%*)( 123456789101010101010101111111111 !!!!!!!!!!", + "test test test test test test test test test test test !@#%*)( 123456789101010101010101111111111 !!!!!!!!!!" ); await page.getByTestId("textarea-text-ExternalLink").click(); diff --git a/src/frontend/tests/end-to-end/toggleComponent.spec.ts b/src/frontend/tests/end-to-end/toggleComponent.spec.ts index 58d909af4..5a8d9a36a 100644 --- a/src/frontend/tests/end-to-end/toggleComponent.spec.ts +++ b/src/frontend/tests/end-to-end/toggleComponent.spec.ts @@ -45,7 +45,7 @@ test("ToggleComponent", async ({ page }) => { await page.locator('//*[@id="showload_hidden"]').click(); expect( - await page.locator('//*[@id="showload_hidden"]').isChecked(), + await page.locator('//*[@id="showload_hidden"]').isChecked() ).toBeTruthy(); await page.getByText("Save Changes", { exact: true }).click(); @@ -81,12 +81,12 @@ test("ToggleComponent", async ({ page }) => { await page.locator('//*[@id="showload_hidden"]').click(); expect( - await page.locator('//*[@id="showload_hidden"]').isChecked(), + await page.locator('//*[@id="showload_hidden"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showmax_concurrency"]').click(); expect( - await page.locator('//*[@id="showmax_concurrency"]').isChecked(), + await page.locator('//*[@id="showmax_concurrency"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showpath"]').click(); @@ -94,22 +94,22 @@ test("ToggleComponent", async ({ page }) => { await page.locator('//*[@id="showrecursive"]').click(); expect( - await page.locator('//*[@id="showrecursive"]').isChecked(), + await page.locator('//*[@id="showrecursive"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showsilent_errors"]').click(); expect( - await page.locator('//*[@id="showsilent_errors"]').isChecked(), + await page.locator('//*[@id="showsilent_errors"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showuse_multithreading"]').click(); expect( - await page.locator('//*[@id="showuse_multithreading"]').isChecked(), + await page.locator('//*[@id="showuse_multithreading"]').isChecked() ).toBeTruthy(); await page.locator('//*[@id="showmax_concurrency"]').click(); expect( - await page.locator('//*[@id="showmax_concurrency"]').isChecked(), + await page.locator('//*[@id="showmax_concurrency"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showpath"]').click(); @@ -117,17 +117,17 @@ test("ToggleComponent", async ({ page }) => { await page.locator('//*[@id="showrecursive"]').click(); expect( - await page.locator('//*[@id="showrecursive"]').isChecked(), + await page.locator('//*[@id="showrecursive"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showsilent_errors"]').click(); expect( - await page.locator('//*[@id="showsilent_errors"]').isChecked(), + await page.locator('//*[@id="showsilent_errors"]').isChecked() ).toBeFalsy(); await page.locator('//*[@id="showuse_multithreading"]').click(); expect( - await page.locator('//*[@id="showuse_multithreading"]').isChecked(), + await page.locator('//*[@id="showuse_multithreading"]').isChecked() ).toBeFalsy(); await page.getByText("Save Changes", { exact: true }).click(); @@ -144,38 +144,38 @@ test("ToggleComponent", async ({ page }) => { await page.locator('//*[@id="showload_hidden"]').click(); expect( - await page.locator('//*[@id="showload_hidden"]').isChecked(), + await page.locator('//*[@id="showload_hidden"]').isChecked() ).toBeTruthy(); expect( - await page.getByTestId("toggle-edit-load_hidden").isChecked(), + await page.getByTestId("toggle-edit-load_hidden").isChecked() ).toBeTruthy(); await page.getByText("Save Changes", { exact: true }).click(); await page.getByTestId("toggle-load_hidden").click(); expect( - await page.getByTestId("toggle-load_hidden").isChecked(), + await page.getByTestId("toggle-load_hidden").isChecked() ).toBeFalsy(); await page.getByTestId("toggle-load_hidden").click(); expect( - await page.getByTestId("toggle-load_hidden").isChecked(), + await page.getByTestId("toggle-load_hidden").isChecked() ).toBeTruthy(); await page.getByTestId("toggle-load_hidden").click(); expect( - await page.getByTestId("toggle-load_hidden").isChecked(), + await page.getByTestId("toggle-load_hidden").isChecked() ).toBeFalsy(); await page.getByTestId("toggle-load_hidden").click(); expect( - await page.getByTestId("toggle-load_hidden").isChecked(), + await page.getByTestId("toggle-load_hidden").isChecked() ).toBeTruthy(); await page.getByTestId("toggle-load_hidden").click(); expect( - await page.getByTestId("toggle-load_hidden").isChecked(), + await page.getByTestId("toggle-load_hidden").isChecked() ).toBeFalsy(); } }); From 627c094907d223b33b1148bce1ed6b798ea78341 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:19:39 -0300 Subject: [PATCH 09/13] chore: Remove simple-git-hooks from package.json --- src/frontend/package.json | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/frontend/package.json b/src/frontend/package.json index efcdd4b43..7f1d95664 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -85,9 +85,6 @@ "format": "npx prettier --write \"{tests,src}/**/*.{js,jsx,ts,tsx,json,md}\" --ignore-path .prettierignore", "type-check": "tsc --noEmit --pretty --project tsconfig.json && vite" }, - "simple-git-hooks": { - "pre-commit": "npx pretty-quick --staged" - }, "eslintConfig": { "extends": [ "react-app", @@ -138,4 +135,4 @@ "ua-parser-js": "^1.0.37", "vite": "^4.5.2" } -} +} \ No newline at end of file From 383ac6e1af89c7d1e0415d7e5cff38969c6da3ba Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:19:56 -0300 Subject: [PATCH 10/13] Update memory example --- .../starter_projects/Langflow Memory Conversation.json | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 55733f720..1d1300e67 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -864,7 +864,7 @@ "show": true, "title_case": false, "type": "str", - "value": "" + "value": "OPENAI_API_KEY" }, "stream": { "advanced": true, @@ -1039,7 +1039,8 @@ "id": "ChatInput-Z9Rn6" } }, - "id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" + "id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "className": "" }, { "source": "MemoryComponent-u6m5G", @@ -1068,12 +1069,13 @@ "id": "MemoryComponent-u6m5G" } }, - "id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}" + "id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "className": "" } ], "viewport": { "x": -511.79726701119625, - "y": 48.514712353620894, + "y": 49.514712353620894, "zoom": 0.4612356948928673 } }, From abb0f818433936c2e905deb875c8060722dbd615 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:21:19 -0300 Subject: [PATCH 11/13] chore: Remove pretty-quick from package.json and package-lock.json --- src/frontend/package-lock.json | 169 --------------------------------- src/frontend/package.json | 1 - 2 files changed, 170 deletions(-) diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 5ef96bea8..b4b86cfd1 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -105,7 +105,6 @@ "prettier": "^2.8.8", "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-tailwindcss": "^0.3.0", - "pretty-quick": "^3.1.3", "simple-git-hooks": "^2.11.1", "tailwindcss": "^3.3.3", "tailwindcss-dotted-background": "^1.1.0", @@ -9956,15 +9955,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10512,165 +10502,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/pretty-quick": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.3.1.tgz", - "integrity": "sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg==", - "dev": true, - "dependencies": { - "execa": "^4.1.0", - "find-up": "^4.1.0", - "ignore": "^5.3.0", - "mri": "^1.2.0", - "picocolors": "^1.0.0", - "picomatch": "^3.0.1", - "tslib": "^2.6.2" - }, - "bin": { - "pretty-quick": "dist/cli.js" - }, - "engines": { - "node": ">=10.13" - }, - "peerDependencies": { - "prettier": "^2.0.0" - } - }, - "node_modules/pretty-quick/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/pretty-quick/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick/node_modules/human-signals": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/pretty-quick/node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pretty-quick/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pretty-quick/node_modules/picomatch": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-3.0.1.tgz", - "integrity": "sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/prismjs": { "version": "1.29.0", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.29.0.tgz", diff --git a/src/frontend/package.json b/src/frontend/package.json index 7f1d95664..ca1717f26 100644 --- a/src/frontend/package.json +++ b/src/frontend/package.json @@ -127,7 +127,6 @@ "prettier": "^2.8.8", "prettier-plugin-organize-imports": "^3.2.3", "prettier-plugin-tailwindcss": "^0.3.0", - "pretty-quick": "^3.1.3", "simple-git-hooks": "^2.11.1", "tailwindcss": "^3.3.3", "tailwindcss-dotted-background": "^1.1.0", From a6c9fe84670f23b62e8b9b86d00226e6c61a1d94 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Thu, 13 Jun 2024 12:23:46 -0300 Subject: [PATCH 12/13] Update memory example params --- .../Langflow Memory Conversation.json | 2160 ++++++++--------- 1 file changed, 1080 insertions(+), 1080 deletions(-) diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json index 1d1300e67..d1bd09650 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Langflow Memory Conversation.json @@ -1,1086 +1,1086 @@ { - "id": "321b1bab-8691-42da-9689-1f12b5d2a48b", - "data": { - "nodes": [ - { - "data": { - "id": "ChatInput-Z9Rn6", - "node": { - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "return_record": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Get chat inputs from the Playground.", - "display_name": "Chat Input", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "ChatInput", - "output_types": [ - "Message", - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "do you know his name?" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "User" - }, - "sender_name": { - "advanced": false, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "User" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "If provided, the message will be stored in the memory.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "ChatInput" - }, - "dragging": false, - "height": 477, - "id": "ChatInput-Z9Rn6", - "position": { - "x": 1283.2700598313072, - "y": 982.5953650473145 - }, - "positionAbsolute": { - "x": 1283.2700598313072, - "y": 982.5953650473145 - }, - "selected": false, - "type": "genericNode", - "width": 384 + "data": { + "edges": [ + { + "className": "", + "data": { + "sourceHandle": { + "baseClasses": [ + "str", + "object", + "Text" + ], + "dataType": "OpenAIModel", + "id": "OpenAIModel-Neuec" + }, + "targetHandle": { + "fieldName": "input_value", + "id": "ChatOutput-cVR7W", + "inputTypes": [ + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-OpenAIModel-Neuec{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}-ChatOutput-cVR7W{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", + "source": "OpenAIModel-Neuec", + "sourceHandle": "{œbaseClassesœ: [œstrœ, œobjectœ, œTextœ], œdataTypeœ: œOpenAIModelœ, œidœ: œOpenAIModel-Neuecœ}", + "style": { + "stroke": "#555" + }, + "target": "ChatOutput-cVR7W", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œChatOutput-cVR7Wœ, œinputTypesœ: [œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "baseClasses": [ + "object", + "str", + "Text" + ], + "dataType": "Prompt", + "id": "Prompt-kykM2" + }, + "targetHandle": { + "fieldName": "input_value", + "id": "OpenAIModel-Neuec", + "inputTypes": [ + "Text", + "Record", + "Prompt" + ], + "type": "str" + } + }, + "id": "reactflow__edge-Prompt-kykM2{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}-OpenAIModel-Neuec{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", + "source": "Prompt-kykM2", + "sourceHandle": "{œbaseClassesœ: [œobjectœ, œstrœ, œTextœ], œdataTypeœ: œPromptœ, œidœ: œPrompt-kykM2œ}", + "target": "OpenAIModel-Neuec", + "targetHandle": "{œfieldNameœ: œinput_valueœ, œidœ: œOpenAIModel-Neuecœ, œinputTypesœ: [œTextœ, œRecordœ, œPromptœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "baseClasses": [ + "Text", + "object", + "Record", + "str" + ], + "dataType": "ChatInput", + "id": "ChatInput-Z9Rn6" + }, + "targetHandle": { + "fieldName": "UserMessage", + "id": "Prompt-kykM2", + "inputTypes": [ + "Document", + "Message", + "Record", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "source": "ChatInput-Z9Rn6", + "sourceHandle": "{œbaseClassesœ: [œTextœ, œobjectœ, œRecordœ, œstrœ], œdataTypeœ: œChatInputœ, œidœ: œChatInput-Z9Rn6œ}", + "target": "Prompt-kykM2", + "targetHandle": "{œfieldNameœ: œUserMessageœ, œidœ: œPrompt-kykM2œ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}" + }, + { + "className": "", + "data": { + "sourceHandle": { + "baseClasses": [ + "str", + "Text", + "object" + ], + "dataType": "MemoryComponent", + "id": "MemoryComponent-u6m5G" + }, + "targetHandle": { + "fieldName": "Context", + "id": "Prompt-kykM2", + "inputTypes": [ + "Document", + "Message", + "Record", + "Text" + ], + "type": "str" + } + }, + "id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", + "source": "MemoryComponent-u6m5G", + "sourceHandle": "{œbaseClassesœ: [œstrœ, œTextœ, œobjectœ], œdataTypeœ: œMemoryComponentœ, œidœ: œMemoryComponent-u6m5Gœ}", + "target": "Prompt-kykM2", + "targetHandle": "{œfieldNameœ: œContextœ, œidœ: œPrompt-kykM2œ, œinputTypesœ: [œDocumentœ, œMessageœ, œRecordœ, œTextœ], œtypeœ: œstrœ}" + } + ], + "nodes": [ + { + "data": { + "id": "ChatInput-Z9Rn6", + "node": { + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "return_record": null, + "sender": null, + "sender_name": null, + "session_id": null }, - { - "data": { - "id": "ChatOutput-cVR7W", - "node": { - "base_classes": [ - "Text", - "object", - "Record", - "str" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "return_record": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Display a chat message in the Playground.", - "display_name": "Chat Output", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "ChatOutput", - "output_types": [ - "Message", - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\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 files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n" - }, - "input_value": { - "advanced": false, - "display_name": "Text", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "input_value", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "sender": { - "advanced": true, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Machine" - }, - "sender_name": { - "advanced": false, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "AI" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "If provided, the message will be stored in the memory.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "ChatOutput" - }, - "dragging": false, - "height": 485, - "id": "ChatOutput-cVR7W", - "position": { - "x": 3154.916355514023, - "y": 851.051882666333 - }, - "positionAbsolute": { - "x": 3154.916355514023, - "y": 851.051882666333 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Retrieves stored chat messages given a specific Session ID.", - "display_name": "Chat Memory", - "id": "MemoryComponent-u6m5G", - "node": { - "base_classes": [ - "str", - "Text", - "object" - ], - "beta": true, - "custom_fields": { - "n_messages": null, - "order": null, - "record_template": null, - "sender": null, - "sender_name": null, - "session_id": null - }, - "description": "Retrieves stored chat messages given a specific Session ID.", - "display_name": "Chat Memory", - "documentation": "", - "field_formatters": {}, - "field_order": [], - "frozen": false, - "icon": "history", - "output_types": [ - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.record import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n record_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=record_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n" - }, - "n_messages": { - "advanced": false, - "display_name": "Number of Messages", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Number of messages to retrieve.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "n_messages", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "int", - "value": 5 - }, - "order": { - "advanced": true, - "display_name": "Order", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Order of the messages.", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "order", - "options": [ - "Ascending", - "Descending" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Descending" - }, - "record_template": { - "advanced": true, - "display_name": "Record Template", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": true, - "name": "record_template", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "{sender_name}: {text}" - }, - "sender": { - "advanced": false, - "display_name": "Sender Type", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "sender", - "options": [ - "Machine", - "User", - "Machine and User" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "Machine and User" - }, - "sender_name": { - "advanced": true, - "display_name": "Sender Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "sender_name", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "session_id": { - "advanced": false, - "display_name": "Session ID", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Session ID of the chat history.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "session_id", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "MySessionID" - } - } - }, - "type": "MemoryComponent" - }, - "dragging": false, - "height": 505, - "id": "MemoryComponent-u6m5G", - "position": { - "x": 1289.9606870058817, - "y": 442.16804561053766 - }, - "positionAbsolute": { - "x": 1289.9606870058817, - "y": 442.16804561053766 - }, - "selected": false, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "description": "Create a prompt template with dynamic variables.", - "display_name": "Prompt", - "id": "Prompt-kykM2", - "node": { - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" - }, - "template": { - "advanced": false, - "display_name": "Template", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "template", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "prompt", - "value": "Previous messages:\n{Context}\n\nUser: {UserMessage}\nAI: " - }, - "Context": { - "field_type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "Context", - "display_name": "Context", - "advanced": false, - "input_types": [ - "Document", - "Message", - "Record", - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "type": "str" - }, - "UserMessage": { - "field_type": "str", - "required": false, - "placeholder": "", - "list": false, - "show": true, - "multiline": true, - "value": "", - "fileTypes": [], - "file_path": "", - "password": false, - "name": "UserMessage", - "display_name": "UserMessage", - "advanced": false, - "input_types": [ - "Document", - "Message", - "Record", - "Text" - ], - "dynamic": false, - "info": "", - "load_from_db": false, - "title_case": false, - "type": "str" - } - }, - "description": "Create a prompt template with dynamic variables.", - "icon": "prompts", - "is_input": null, - "is_output": null, - "is_composition": null, - "base_classes": [ - "object", - "str", - "Text" - ], - "name": "", - "display_name": "Prompt", - "documentation": "", - "custom_fields": { - "template": [ - "Context", - "UserMessage" - ] - }, - "output_types": [ - "Prompt" - ], - "full_path": null, - "field_formatters": {}, - "frozen": false, - "field_order": [], - "beta": false, - "error": null - }, - "type": "Prompt" - }, - "dragging": false, - "height": 513, - "id": "Prompt-kykM2", - "position": { - "x": 1890.2582485007167, - "y": 753.3797365481901 - }, - "positionAbsolute": { - "x": 1890.2582485007167, - "y": 753.3797365481901 - }, - "selected": true, - "type": "genericNode", - "width": 384 - }, - { - "data": { - "id": "OpenAIModel-Neuec", - "node": { - "base_classes": [ - "str", - "object", - "Text" - ], - "beta": false, - "custom_fields": { - "input_value": null, - "max_tokens": null, - "model_kwargs": null, - "model_name": null, - "openai_api_base": null, - "openai_api_key": null, - "stream": null, - "system_message": null, - "temperature": null - }, - "description": "Generates text using OpenAI LLMs.", - "display_name": "OpenAI", - "documentation": "", - "field_formatters": {}, - "field_order": [ - "max_tokens", - "model_kwargs", - "model_name", - "openai_api_base", - "openai_api_key", - "temperature", - "input_value", - "system_message", - "stream" - ], - "frozen": false, - "icon": "OpenAI", - "output_types": [ - "Text" - ], - "template": { - "_type": "CustomComponent", - "code": { - "advanced": true, - "dynamic": true, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": true, - "name": "code", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "code", - "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n" - }, - "input_value": { - "advanced": false, - "display_name": "Input", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text", - "Record", - "Prompt" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "input_value", - "password": false, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "str" - }, - "max_tokens": { - "advanced": true, - "display_name": "Max Tokens", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "max_tokens", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "int", - "value": 256 - }, - "model_kwargs": { - "advanced": true, - "display_name": "Model Kwargs", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "model_kwargs", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "NestedDict", - "value": {} - }, - "model_name": { - "advanced": false, - "display_name": "Model Name", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "input_types": [ - "Text" - ], - "list": true, - "load_from_db": false, - "multiline": false, - "name": "model_name", - "options": [ - "gpt-4o", - "gpt-4-turbo", - "gpt-4-turbo-preview", - "gpt-3.5-turbo", - "gpt-3.5-turbo-0125" - ], - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str", - "value": "gpt-3.5-turbo" - }, - "openai_api_base": { - "advanced": true, - "display_name": "OpenAI API Base", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "openai_api_base", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "openai_api_key": { - "advanced": false, - "display_name": "OpenAI API Key", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "The OpenAI API Key to use for the OpenAI model.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": true, - "multiline": false, - "name": "openai_api_key", - "password": true, - "placeholder": "", - "required": true, - "show": true, - "title_case": false, - "type": "str", - "value": "OPENAI_API_KEY" - }, - "stream": { - "advanced": true, - "display_name": "Stream", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "Stream the response from the model. Streaming works only in Chat.", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "stream", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "bool", - "value": false - }, - "system_message": { - "advanced": true, - "display_name": "System Message", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "System message to pass to the model.", - "input_types": [ - "Text" - ], - "list": false, - "load_from_db": false, - "multiline": false, - "name": "system_message", - "password": false, - "placeholder": "", - "required": false, - "show": true, - "title_case": false, - "type": "str" - }, - "temperature": { - "advanced": false, - "display_name": "Temperature", - "dynamic": false, - "fileTypes": [], - "file_path": "", - "info": "", - "list": false, - "load_from_db": false, - "multiline": false, - "name": "temperature", - "password": false, - "placeholder": "", - "rangeSpec": { - "max": 1, - "min": -1, - "step": 0.1, - "step_type": "float" - }, - "required": false, - "show": true, - "title_case": false, - "type": "float", - "value": "0.2" - } - } - }, - "type": "OpenAIModel" - }, - "dragging": false, - "height": 571, - "id": "OpenAIModel-Neuec", - "position": { - "x": 2561.5850334731617, - "y": 553.2745131130916 - }, - "positionAbsolute": { - "x": 2561.5850334731617, - "y": 553.2745131130916 - }, - "selected": false, - "type": "genericNode", - "width": 384 + "description": "Get chat inputs from the Playground.", + "display_name": "Chat Input", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "ChatInput", + "output_types": [ + "Message", + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.schema.message import Message\nfrom langflow.field_typing import Text\nfrom typing import Union\n\n\nclass ChatInput(ChatComponent):\n display_name = \"Chat Input\"\n description = \"Get chat inputs from the Playground.\"\n icon = \"ChatInput\"\n\n def build_config(self):\n build_config = super().build_config()\n build_config[\"input_value\"] = {\n \"input_types\": [],\n \"display_name\": \"Text\",\n \"multiline\": True,\n }\n build_config[\"return_message\"] = {\n \"display_name\": \"Return Record\",\n \"advanced\": True,\n }\n\n return build_config\n\n def build(\n self,\n sender: Optional[str] = \"User\",\n sender_name: Optional[str] = \"User\",\n input_value: Optional[str] = None,\n files: Optional[list[str]] = None,\n session_id: Optional[str] = None,\n return_message: Optional[bool] = True,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n files=files,\n session_id=session_id,\n return_message=return_message,\n )\n" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "do you know his name?" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "User" + }, + "sender_name": { + "advanced": false, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "User" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "If provided, the message will be stored in the memory.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } } - ], - "edges": [ - { - "className": "", - "data": { - "sourceHandle": { - "baseClasses": [ - "str", - "object", - "Text" - ], - "dataType": "OpenAIModel", - "id": "OpenAIModel-Neuec" - }, - "targetHandle": { - "fieldName": "input_value", - "id": "ChatOutput-cVR7W", - "inputTypes": [ - "Text" - ], - "type": "str" - } - }, - "id": "reactflow__edge-OpenAIModel-Neuec{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}-ChatOutput-cVR7W{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}", - "source": "OpenAIModel-Neuec", - "sourceHandle": "{œbaseClassesœ:[œstrœ,œobjectœ,œTextœ],œdataTypeœ:œOpenAIModelœ,œidœ:œOpenAIModel-Neuecœ}", - "style": { - "stroke": "#555" - }, - "target": "ChatOutput-cVR7W", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œChatOutput-cVR7Wœ,œinputTypesœ:[œTextœ],œtypeœ:œstrœ}" + }, + "type": "ChatInput" + }, + "dragging": false, + "height": 477, + "id": "ChatInput-Z9Rn6", + "position": { + "x": 1283.2700598313072, + "y": 982.5953650473145 + }, + "positionAbsolute": { + "x": 1283.2700598313072, + "y": 982.5953650473145 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "ChatOutput-cVR7W", + "node": { + "base_classes": [ + "Text", + "object", + "Record", + "str" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "return_record": null, + "sender": null, + "sender_name": null, + "session_id": null }, - { - "source": "Prompt-kykM2", - "sourceHandle": "{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}", - "target": "OpenAIModel-Neuec", - "targetHandle": "{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "input_value", - "id": "OpenAIModel-Neuec", - "inputTypes": [ - "Text", - "Record", - "Prompt" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "object", - "str", - "Text" - ], - "dataType": "Prompt", - "id": "Prompt-kykM2" - } - }, - "id": "reactflow__edge-Prompt-kykM2{œbaseClassesœ:[œobjectœ,œstrœ,œTextœ],œdataTypeœ:œPromptœ,œidœ:œPrompt-kykM2œ}-OpenAIModel-Neuec{œfieldNameœ:œinput_valueœ,œidœ:œOpenAIModel-Neuecœ,œinputTypesœ:[œTextœ,œRecordœ,œPromptœ],œtypeœ:œstrœ}", - "className": "" - }, - { - "source": "ChatInput-Z9Rn6", - "sourceHandle": "{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}", - "target": "Prompt-kykM2", - "targetHandle": "{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "UserMessage", - "id": "Prompt-kykM2", - "inputTypes": [ - "Document", - "Message", - "Record", - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "Text", - "object", - "Record", - "str" - ], - "dataType": "ChatInput", - "id": "ChatInput-Z9Rn6" - } - }, - "id": "reactflow__edge-ChatInput-Z9Rn6{œbaseClassesœ:[œTextœ,œobjectœ,œRecordœ,œstrœ],œdataTypeœ:œChatInputœ,œidœ:œChatInput-Z9Rn6œ}-Prompt-kykM2{œfieldNameœ:œUserMessageœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "className": "" - }, - { - "source": "MemoryComponent-u6m5G", - "sourceHandle": "{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}", - "target": "Prompt-kykM2", - "targetHandle": "{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "data": { - "targetHandle": { - "fieldName": "Context", - "id": "Prompt-kykM2", - "inputTypes": [ - "Document", - "Message", - "Record", - "Text" - ], - "type": "str" - }, - "sourceHandle": { - "baseClasses": [ - "str", - "Text", - "object" - ], - "dataType": "MemoryComponent", - "id": "MemoryComponent-u6m5G" - } - }, - "id": "reactflow__edge-MemoryComponent-u6m5G{œbaseClassesœ:[œstrœ,œTextœ,œobjectœ],œdataTypeœ:œMemoryComponentœ,œidœ:œMemoryComponent-u6m5Gœ}-Prompt-kykM2{œfieldNameœ:œContextœ,œidœ:œPrompt-kykM2œ,œinputTypesœ:[œDocumentœ,œMessageœ,œRecordœ,œTextœ],œtypeœ:œstrœ}", - "className": "" + "description": "Display a chat message in the Playground.", + "display_name": "Chat Output", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "ChatOutput", + "output_types": [ + "Message", + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional, Union\n\nfrom langflow.base.io.chat import ChatComponent\nfrom langflow.field_typing import Text\nfrom langflow.schema.message import Message\n\n\nclass ChatOutput(ChatComponent):\n display_name = \"Chat Output\"\n description = \"Display a chat message in the Playground.\"\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 files: Optional[list[str]] = None,\n return_message: Optional[bool] = False,\n ) -> Union[Message, Text]:\n return super().build_with_record(\n sender=sender,\n sender_name=sender_name,\n input_value=input_value,\n session_id=session_id,\n files=files,\n return_message=return_message,\n )\n" + }, + "input_value": { + "advanced": false, + "display_name": "Text", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "input_value", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "sender": { + "advanced": true, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Machine" + }, + "sender_name": { + "advanced": false, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "AI" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "If provided, the message will be stored in the memory.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } } - ], - "viewport": { - "x": -511.79726701119625, - "y": 49.514712353620894, - "zoom": 0.4612356948928673 - } - }, - "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", - "name": "Memory Chatbot", - "last_tested_version": "1.0.0a54", - "is_component": false + }, + "type": "ChatOutput" + }, + "dragging": false, + "height": 485, + "id": "ChatOutput-cVR7W", + "position": { + "x": 3154.916355514023, + "y": 851.051882666333 + }, + "positionAbsolute": { + "x": 3154.916355514023, + "y": 851.051882666333 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Retrieves stored chat messages given a specific Session ID.", + "display_name": "Chat Memory", + "id": "MemoryComponent-u6m5G", + "node": { + "base_classes": [ + "str", + "Text", + "object" + ], + "beta": true, + "custom_fields": { + "n_messages": null, + "order": null, + "record_template": null, + "sender": null, + "sender_name": null, + "session_id": null + }, + "description": "Retrieves stored chat messages given a specific Session ID.", + "display_name": "Chat Memory", + "documentation": "", + "field_formatters": {}, + "field_order": [], + "frozen": false, + "icon": "history", + "output_types": [ + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langflow.base.memory.memory import BaseMemoryComponent\nfrom langflow.field_typing import Text\nfrom langflow.helpers.record import messages_to_text\nfrom langflow.memory import get_messages\nfrom langflow.schema.message import Message\n\n\nclass MemoryComponent(BaseMemoryComponent):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages given a specific Session ID.\"\n beta: bool = True\n icon = \"history\"\n\n def build_config(self):\n return {\n \"sender\": {\n \"options\": [\"Machine\", \"User\", \"Machine and User\"],\n \"display_name\": \"Sender Type\",\n },\n \"sender_name\": {\"display_name\": \"Sender Name\", \"advanced\": True},\n \"n_messages\": {\n \"display_name\": \"Number of Messages\",\n \"info\": \"Number of messages to retrieve.\",\n },\n \"session_id\": {\n \"display_name\": \"Session ID\",\n \"info\": \"Session ID of the chat history.\",\n \"input_types\": [\"Text\"],\n },\n \"order\": {\n \"options\": [\"Ascending\", \"Descending\"],\n \"display_name\": \"Order\",\n \"info\": \"Order of the messages.\",\n \"advanced\": True,\n },\n \"record_template\": {\n \"display_name\": \"Record Template\",\n \"multiline\": True,\n \"info\": \"Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.\",\n \"advanced\": True,\n },\n }\n\n def get_messages(self, **kwargs) -> list[Message]:\n # Validate kwargs by checking if it contains the correct keys\n if \"sender\" not in kwargs:\n kwargs[\"sender\"] = None\n if \"sender_name\" not in kwargs:\n kwargs[\"sender_name\"] = None\n if \"session_id\" not in kwargs:\n kwargs[\"session_id\"] = None\n if \"limit\" not in kwargs:\n kwargs[\"limit\"] = 5\n if \"order\" not in kwargs:\n kwargs[\"order\"] = \"Descending\"\n\n kwargs[\"order\"] = \"DESC\" if kwargs[\"order\"] == \"Descending\" else \"ASC\"\n if kwargs[\"sender\"] == \"Machine and User\":\n kwargs[\"sender\"] = None\n return get_messages(**kwargs)\n\n def build(\n self,\n sender: Optional[str] = \"Machine and User\",\n sender_name: Optional[str] = None,\n session_id: Optional[str] = None,\n n_messages: int = 5,\n order: Optional[str] = \"Descending\",\n record_template: Optional[str] = \"{sender_name}: {text}\",\n ) -> Text:\n messages = self.get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n messages_str = messages_to_text(template=record_template or \"\", messages=messages)\n self.status = messages_str\n return messages_str\n" + }, + "n_messages": { + "advanced": false, + "display_name": "Number of Messages", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Number of messages to retrieve.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "n_messages", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "int", + "value": 5 + }, + "order": { + "advanced": true, + "display_name": "Order", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Order of the messages.", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "order", + "options": [ + "Ascending", + "Descending" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Descending" + }, + "record_template": { + "advanced": true, + "display_name": "Record Template", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "record_template", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "{sender_name}: {text}" + }, + "sender": { + "advanced": false, + "display_name": "Sender Type", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "sender", + "options": [ + "Machine", + "User", + "Machine and User" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "Machine and User" + }, + "sender_name": { + "advanced": true, + "display_name": "Sender Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "sender_name", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "session_id": { + "advanced": false, + "display_name": "Session ID", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Session ID of the chat history.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "session_id", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "MySessionID" + } + } + }, + "type": "MemoryComponent" + }, + "dragging": false, + "height": 505, + "id": "MemoryComponent-u6m5G", + "position": { + "x": 1289.9606870058817, + "y": 442.16804561053766 + }, + "positionAbsolute": { + "x": 1289.9606870058817, + "y": 442.16804561053766 + }, + "selected": false, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "id": "Prompt-kykM2", + "node": { + "base_classes": [ + "object", + "str", + "Text" + ], + "beta": false, + "custom_fields": { + "template": [ + "Context", + "UserMessage" + ] + }, + "description": "Create a prompt template with dynamic variables.", + "display_name": "Prompt", + "documentation": "", + "error": null, + "field_formatters": {}, + "field_order": [], + "frozen": false, + "full_path": null, + "icon": "prompts", + "is_composition": null, + "is_input": null, + "is_output": null, + "name": "", + "output_types": [ + "Prompt" + ], + "template": { + "Context": { + "advanced": false, + "display_name": "Context", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "Message", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "Context", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "UserMessage": { + "advanced": false, + "display_name": "UserMessage", + "dynamic": false, + "field_type": "str", + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Document", + "Message", + "Record", + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": true, + "name": "UserMessage", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "" + }, + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from langflow.custom import CustomComponent\nfrom langflow.field_typing import TemplateField\nfrom langflow.field_typing.prompt import Prompt\n\n\nclass PromptComponent(CustomComponent):\n display_name: str = \"Prompt\"\n description: str = \"Create a prompt template with dynamic variables.\"\n icon = \"prompts\"\n\n def build_config(self):\n return {\n \"template\": TemplateField(display_name=\"Template\"),\n \"code\": TemplateField(advanced=True),\n }\n\n async def build(\n self,\n template: Prompt,\n **kwargs,\n ) -> Prompt:\n prompt = await Prompt.from_template_and_variables(template, kwargs)\n self.status = prompt.format_text()\n return prompt\n" + }, + "template": { + "advanced": false, + "display_name": "Template", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "template", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "prompt", + "value": "Previous messages:\n{Context}\n\nUser: {UserMessage}\nAI: " + } + } + }, + "type": "Prompt" + }, + "dragging": false, + "height": 513, + "id": "Prompt-kykM2", + "position": { + "x": 1890.2582485007167, + "y": 753.3797365481901 + }, + "positionAbsolute": { + "x": 1890.2582485007167, + "y": 753.3797365481901 + }, + "selected": true, + "type": "genericNode", + "width": 384 + }, + { + "data": { + "id": "OpenAIModel-Neuec", + "node": { + "base_classes": [ + "str", + "object", + "Text" + ], + "beta": false, + "custom_fields": { + "input_value": null, + "max_tokens": null, + "model_kwargs": null, + "model_name": null, + "openai_api_base": null, + "openai_api_key": null, + "stream": null, + "system_message": null, + "temperature": null + }, + "description": "Generates text using OpenAI LLMs.", + "display_name": "OpenAI", + "documentation": "", + "field_formatters": {}, + "field_order": [ + "max_tokens", + "model_kwargs", + "model_name", + "openai_api_base", + "openai_api_key", + "temperature", + "input_value", + "system_message", + "stream" + ], + "frozen": false, + "icon": "OpenAI", + "output_types": [ + "Text" + ], + "template": { + "_type": "CustomComponent", + "code": { + "advanced": true, + "dynamic": true, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": true, + "name": "code", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "code", + "value": "from typing import Optional\n\nfrom langchain_openai import ChatOpenAI\nfrom pydantic.v1 import SecretStr\n\nfrom langflow.base.constants import STREAM_INFO_TEXT\nfrom langflow.base.models.model import LCModelComponent\nfrom langflow.base.models.openai_constants import MODEL_NAMES\nfrom langflow.field_typing import NestedDict, Text\n\n\nclass OpenAIModelComponent(LCModelComponent):\n display_name = \"OpenAI\"\n description = \"Generates text using OpenAI LLMs.\"\n icon = \"OpenAI\"\n\n field_order = [\n \"max_tokens\",\n \"model_kwargs\",\n \"model_name\",\n \"openai_api_base\",\n \"openai_api_key\",\n \"temperature\",\n \"input_value\",\n \"system_message\",\n \"stream\",\n ]\n\n def build_config(self):\n return {\n \"input_value\": {\"display_name\": \"Input\", \"input_types\": [\"Text\", \"Record\", \"Prompt\"]},\n \"max_tokens\": {\n \"display_name\": \"Max Tokens\",\n \"advanced\": True,\n \"info\": \"The maximum number of tokens to generate. Set to 0 for unlimited tokens.\",\n },\n \"model_kwargs\": {\n \"display_name\": \"Model Kwargs\",\n \"advanced\": True,\n },\n \"model_name\": {\n \"display_name\": \"Model Name\",\n \"advanced\": False,\n \"options\": MODEL_NAMES,\n },\n \"openai_api_base\": {\n \"display_name\": \"OpenAI API Base\",\n \"advanced\": True,\n \"info\": (\n \"The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\\n\\n\"\n \"You can change this to use other APIs like JinaChat, LocalAI and Prem.\"\n ),\n },\n \"openai_api_key\": {\n \"display_name\": \"OpenAI API Key\",\n \"info\": \"The OpenAI API Key to use for the OpenAI model.\",\n \"advanced\": False,\n \"password\": True,\n },\n \"temperature\": {\n \"display_name\": \"Temperature\",\n \"advanced\": False,\n \"value\": 0.1,\n },\n \"stream\": {\n \"display_name\": \"Stream\",\n \"info\": STREAM_INFO_TEXT,\n \"advanced\": True,\n },\n \"system_message\": {\n \"display_name\": \"System Message\",\n \"info\": \"System message to pass to the model.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n input_value: Text,\n openai_api_key: str,\n temperature: float = 0.1,\n model_name: str = \"gpt-3.5-turbo\",\n max_tokens: Optional[int] = 256,\n model_kwargs: NestedDict = {},\n openai_api_base: Optional[str] = None,\n stream: bool = False,\n system_message: Optional[str] = None,\n ) -> Text:\n if not openai_api_base:\n openai_api_base = \"https://api.openai.com/v1\"\n if openai_api_key:\n api_key = SecretStr(openai_api_key)\n else:\n api_key = None\n\n output = ChatOpenAI(\n max_tokens=max_tokens or None,\n model_kwargs=model_kwargs,\n model=model_name,\n base_url=openai_api_base,\n api_key=api_key,\n temperature=temperature,\n )\n\n return self.get_chat_result(output, stream, input_value, system_message)\n" + }, + "input_value": { + "advanced": false, + "display_name": "Input", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text", + "Record", + "Prompt" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "input_value", + "password": false, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str" + }, + "max_tokens": { + "advanced": true, + "display_name": "Max Tokens", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The maximum number of tokens to generate. Set to 0 for unlimited tokens.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "max_tokens", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "int", + "value": 256 + }, + "model_kwargs": { + "advanced": true, + "display_name": "Model Kwargs", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "model_kwargs", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "NestedDict", + "value": {} + }, + "model_name": { + "advanced": false, + "display_name": "Model Name", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "input_types": [ + "Text" + ], + "list": true, + "load_from_db": false, + "multiline": false, + "name": "model_name", + "options": [ + "gpt-4o", + "gpt-4-turbo", + "gpt-4-turbo-preview", + "gpt-3.5-turbo", + "gpt-3.5-turbo-0125" + ], + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str", + "value": "gpt-3.5-turbo" + }, + "openai_api_base": { + "advanced": true, + "display_name": "OpenAI API Base", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The base URL of the OpenAI API. Defaults to https://api.openai.com/v1.\n\nYou can change this to use other APIs like JinaChat, LocalAI and Prem.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "openai_api_base", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "openai_api_key": { + "advanced": false, + "display_name": "OpenAI API Key", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "The OpenAI API Key to use for the OpenAI model.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": true, + "multiline": false, + "name": "openai_api_key", + "password": true, + "placeholder": "", + "required": true, + "show": true, + "title_case": false, + "type": "str", + "value": "OPENAI_API_KEY" + }, + "stream": { + "advanced": true, + "display_name": "Stream", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "Stream the response from the model. Streaming works only in Chat.", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "stream", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "bool", + "value": false + }, + "system_message": { + "advanced": true, + "display_name": "System Message", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "System message to pass to the model.", + "input_types": [ + "Text" + ], + "list": false, + "load_from_db": false, + "multiline": false, + "name": "system_message", + "password": false, + "placeholder": "", + "required": false, + "show": true, + "title_case": false, + "type": "str" + }, + "temperature": { + "advanced": false, + "display_name": "Temperature", + "dynamic": false, + "fileTypes": [], + "file_path": "", + "info": "", + "list": false, + "load_from_db": false, + "multiline": false, + "name": "temperature", + "password": false, + "placeholder": "", + "rangeSpec": { + "max": 1, + "min": -1, + "step": 0.1, + "step_type": "float" + }, + "required": false, + "show": true, + "title_case": false, + "type": "float", + "value": "0.2" + } + } + }, + "type": "OpenAIModel" + }, + "dragging": false, + "height": 571, + "id": "OpenAIModel-Neuec", + "position": { + "x": 2561.5850334731617, + "y": 553.2745131130916 + }, + "positionAbsolute": { + "x": 2561.5850334731617, + "y": 553.2745131130916 + }, + "selected": false, + "type": "genericNode", + "width": 384 + } + ], + "viewport": { + "x": -511.79726701119625, + "y": 49.514712353620894, + "zoom": 0.4612356948928673 + } + }, + "description": "This project can be used as a starting point for building a Chat experience with user specific memory. You can set a different Session ID to start a new message history.", + "id": "321b1bab-8691-42da-9689-1f12b5d2a48b", + "is_component": false, + "last_tested_version": "1.0.0a54", + "name": "Memory Chatbot" } \ No newline at end of file From 5f14aece1a5cbbdc450b168f6b4dd56eb3605b74 Mon Sep 17 00:00:00 2001 From: italojohnny Date: Thu, 13 Jun 2024 12:30:20 -0300 Subject: [PATCH 13/13] bugfix --- src/backend/base/langflow/graph/utils.py | 3 +-- src/backend/base/langflow/interface/initialize/loading.py | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/backend/base/langflow/graph/utils.py b/src/backend/base/langflow/graph/utils.py index 06b7ca90a..89db4f0aa 100644 --- a/src/backend/base/langflow/graph/utils.py +++ b/src/backend/base/langflow/graph/utils.py @@ -65,9 +65,8 @@ def serialize_field(value): return value -def get_artifact_type(custom_component, build_result) -> str: +def get_artifact_type(value, build_result) -> str: result = ArtifactType.UNKNOWN - value = custom_component.repr_value match value: case Record(): result = ArtifactType.RECORD diff --git a/src/backend/base/langflow/interface/initialize/loading.py b/src/backend/base/langflow/interface/initialize/loading.py index afe653e42..67403c2fe 100644 --- a/src/backend/base/langflow/interface/initialize/loading.py +++ b/src/backend/base/langflow/interface/initialize/loading.py @@ -132,11 +132,12 @@ async def instantiate_custom_component(params, user_id, vertex, fallback_to_env_ raw = custom_component.repr_value if hasattr(raw, "data") and raw is not None: raw = raw.data - elif hasattr(raw, "model_dump") and raw is not None: raw = raw.model_dump() + if raw is None and isinstance(build_result, (dict, Record, str)): + raw = build_result.data if isinstance(build_result, Record) else build_result - artifact_type = get_artifact_type(custom_component, build_result) + artifact_type = get_artifact_type(custom_component.repr_value or raw, build_result) raw = post_process_raw(raw, artifact_type) artifact = {"repr": custom_repr, "raw": raw, "type": artifact_type} return custom_component, build_result, artifact