From e28962cbc4cda20e57719956a07de6fa965e922f Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Tue, 11 Jun 2024 05:33:23 -0700 Subject: [PATCH 1/2] Update Couchbase component and package versions (#2138) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: Update Couchbase component to handle import errors * chore: Update package versions in pyproject.toml and poetry.lock * refactor: Fix encoding issue in read_text_file function * 🐛 (parse.py): fix issue where method was always set to "post" when data or data binary was provided in curl command * refactor: Fix string formatting in MonitorService delete_messages method * fix: Update Couchbase import instructions in CouchbaseComponent * refactor: Fix encoding issue in read_text_file function --- poetry.lock | 56 +-- pyproject.toml | 2 +- src/backend/base/langflow/base/curl/parse.py | 7 +- src/backend/base/langflow/base/data/utils.py | 4 + .../components/vectorstores/Couchbase.py | 20 +- .../VectorStore-RAG-Flows.json | 472 ++++++++++++++---- .../base/langflow/services/monitor/service.py | 2 +- src/backend/base/poetry.lock | 32 +- src/backend/base/pyproject.toml | 2 +- 9 files changed, 431 insertions(+), 166 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0ee09bb52..0a0c1b587 100644 --- a/poetry.lock +++ b/poetry.lock @@ -471,17 +471,17 @@ files = [ [[package]] name = "boto3" -version = "1.34.122" +version = "1.34.123" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.122-py3-none-any.whl", hash = "sha256:b2d7400ff84fa547e53b3d9acfa3c95d65d45b5886ba1ede1f7df4768d1cc0b1"}, - {file = "boto3-1.34.122.tar.gz", hash = "sha256:56840d8ce91654d182f1c113f0791fa2113c3aa43230c50b4481f235348a6037"}, + {file = "boto3-1.34.123-py3-none-any.whl", hash = "sha256:56bec52d485d5670ce96d53ae7b2cd4ae4e8a705fb2298a21093cdd77d642331"}, + {file = "boto3-1.34.123.tar.gz", hash = "sha256:42b140fc850cf261ee4b1e8ef527fa071b1f1592a6d6a68d34b29f37cc46b4dd"}, ] [package.dependencies] -botocore = ">=1.34.122,<1.35.0" +botocore = ">=1.34.123,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -490,13 +490,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.122" +version = "1.34.123" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.122-py3-none-any.whl", hash = "sha256:6d75df3af831b62f0c7baa109728d987e0a8d34bfadf0476eb32e2f29a079a36"}, - {file = "botocore-1.34.122.tar.gz", hash = "sha256:9374e16a36f1062c3e27816e8599b53eba99315dfac71cc84fc3aee3f5d3cbe3"}, + {file = "botocore-1.34.123-py3-none-any.whl", hash = "sha256:8c34ada2a708c82e7174bff700611643db7ce2cb18f1130c35045c24310d299d"}, + {file = "botocore-1.34.123.tar.gz", hash = "sha256:a8577f6574600c4d159b5cd103ee05744a443d77f7778304e17307940b369c4f"}, ] [package.dependencies] @@ -2737,13 +2737,13 @@ protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4 [[package]] name = "google-cloud-storage" -version = "2.16.0" +version = "2.17.0" description = "Google Cloud Storage API client library" optional = false python-versions = ">=3.7" files = [ - {file = "google-cloud-storage-2.16.0.tar.gz", hash = "sha256:dda485fa503710a828d01246bd16ce9db0823dc51bbca742ce96a6817d58669f"}, - {file = "google_cloud_storage-2.16.0-py2.py3-none-any.whl", hash = "sha256:91a06b96fb79cf9cdfb4e759f178ce11ea885c79938f89590344d079305f5852"}, + {file = "google-cloud-storage-2.17.0.tar.gz", hash = "sha256:49378abff54ef656b52dca5ef0f2eba9aa83dc2b2c72c78714b03a1a95fe9388"}, + {file = "google_cloud_storage-2.17.0-py2.py3-none-any.whl", hash = "sha256:5b393bc766b7a3bc6f5407b9e665b2450d36282614b7945e570b3480a456d1e1"}, ] [package.dependencies] @@ -2862,13 +2862,13 @@ dev = ["Pillow", "absl-py", "black", "ipython", "nose2", "pandas", "pytype", "py [[package]] name = "google-resumable-media" -version = "2.7.0" +version = "2.7.1" description = "Utilities for Google Media Downloads and Resumable Uploads" optional = false -python-versions = ">= 3.7" +python-versions = ">=3.7" files = [ - {file = "google-resumable-media-2.7.0.tar.gz", hash = "sha256:5f18f5fa9836f4b083162064a1c2c98c17239bfda9ca50ad970ccf905f3e625b"}, - {file = "google_resumable_media-2.7.0-py2.py3-none-any.whl", hash = "sha256:79543cfe433b63fd81c0844b7803aba1bb8950b47bedf7d980c38fa123937e08"}, + {file = "google-resumable-media-2.7.1.tar.gz", hash = "sha256:eae451a7b2e2cdbaaa0fd2eb00cc8a1ee5e95e16b55597359cbc3d27d7d90e33"}, + {file = "google_resumable_media-2.7.1-py2.py3-none-any.whl", hash = "sha256:103ebc4ba331ab1bfdac0250f8033627a2cd7cde09e7ccff9181e31ba4315b2c"}, ] [package.dependencies] @@ -3954,13 +3954,13 @@ files = [ [[package]] name = "jsonpointer" -version = "2.4" +version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] [[package]] @@ -4360,7 +4360,7 @@ six = "*" [[package]] name = "langflow-base" -version = "0.0.60" +version = "0.0.61" description = "A Python package with a built-in web application" optional = false python-versions = ">=3.10,<3.13" @@ -4441,13 +4441,13 @@ openai = ["openai (>=0.27.8)"] [[package]] name = "langsmith" -version = "0.1.75" +version = "0.1.76" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.75-py3-none-any.whl", hash = "sha256:d08b08dd6b3fa4da170377f95123d77122ef4c52999d10fff4ae08ff70d07aed"}, - {file = "langsmith-0.1.75.tar.gz", hash = "sha256:61274e144ea94c297dd78ce03e6dfae18459fe9bd8ab5094d61a0c4816561279"}, + {file = "langsmith-0.1.76-py3-none-any.whl", hash = "sha256:4b8cb14f2233d9673ce9e6e3d545359946d9690a2c1457ab01e7459ec97b964e"}, + {file = "langsmith-0.1.76.tar.gz", hash = "sha256:5829f997495c0f9a39f91fe0a57e0cb702e8642e6948945f5bb9f46337db7732"}, ] [package.dependencies] @@ -4457,13 +4457,13 @@ requests = ">=2,<3" [[package]] name = "litellm" -version = "1.40.7" +version = "1.40.8" description = "Library to easily interface with LLM API providers" optional = false python-versions = "!=2.7.*,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,!=3.7.*,>=3.8" files = [ - {file = "litellm-1.40.7-py3-none-any.whl", hash = "sha256:c98dd8733e632aba16f14bf82e56f7159222097a6d085b242a3140b5d3e7baa4"}, - {file = "litellm-1.40.7.tar.gz", hash = "sha256:557bb19e8e484d0dfe8e4eaa9ccefc888617852988a46d6e7adc41585a2c0600"}, + {file = "litellm-1.40.8-py3-none-any.whl", hash = "sha256:cd0c313423dad49224696c45ac02c574abcaed6666c597543c2318b3521f4320"}, + {file = "litellm-1.40.8.tar.gz", hash = "sha256:8878d2437ac50bcc6f39ded1729e2113eb5fee645fcebcd32fc241c529a21c00"}, ] [package.dependencies] @@ -9532,13 +9532,13 @@ xlsx = ["networkx", "openpyxl", "pandas", "xlrd"] [[package]] name = "unstructured-client" -version = "0.23.2" +version = "0.23.3" description = "Python Client SDK for Unstructured API" optional = false python-versions = ">=3.8" files = [ - {file = "unstructured-client-0.23.2.tar.gz", hash = "sha256:26864737a6c27471cba8bcb714e4e31038f62f84552b3ead5f241bc56fa42288"}, - {file = "unstructured_client-0.23.2-py3-none-any.whl", hash = "sha256:b3be91e7c2498aa9108a43dde4cbb75e450a87fabb450f0687c1900da7da73f6"}, + {file = "unstructured-client-0.23.3.tar.gz", hash = "sha256:3aa6ad1365c09c17eaa9367d310e457bfe9bd9e23705567811ab2fdb41d66406"}, + {file = "unstructured_client-0.23.3-py3-none-any.whl", hash = "sha256:446469fd263f4b3eec1a982e84c04b2680f9a4e560ae0968d6e0ff2f4eead233"}, ] [package.dependencies] diff --git a/pyproject.toml b/pyproject.toml index c766ac13f..cf967857c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "langflow" -version = "1.0.0a49" +version = "1.0.0a50" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ diff --git a/src/backend/base/langflow/base/curl/parse.py b/src/backend/base/langflow/base/curl/parse.py index 7a5eff92b..c3c2d31ce 100644 --- a/src/backend/base/langflow/base/curl/parse.py +++ b/src/backend/base/langflow/base/curl/parse.py @@ -64,21 +64,20 @@ def parse_curl_command(curl_command): "cookies": {}, } args = args_template.copy() - + method_on_curl = None i = 0 while i < len(tokens): token = tokens[i] if token == "-X": i += 1 args["method"] = tokens[i].lower() + method_on_curl = tokens[i].lower() elif token in ("-d", "--data"): i += 1 args["data"] = tokens[i] - args["method"] = "post" elif token in ("-b", "--data-binary", "--data-raw"): i += 1 args["data_binary"] = tokens[i] - args["method"] = "post" elif token in ("-H", "--header"): i += 1 args["headers"].append(tokens[i]) @@ -106,6 +105,8 @@ def parse_curl_command(curl_command): args["url"] = token i += 1 + args["method"] = method_on_curl or args["method"] + return ParsedArgs(**args) diff --git a/src/backend/base/langflow/base/data/utils.py b/src/backend/base/langflow/base/data/utils.py index c72c9b5b8..0c7cc3fef 100644 --- a/src/backend/base/langflow/base/data/utils.py +++ b/src/backend/base/langflow/base/data/utils.py @@ -3,6 +3,7 @@ import xml.etree.ElementTree as ET from concurrent import futures from pathlib import Path from typing import Callable, List, Optional, Text + import chardet import yaml @@ -94,6 +95,9 @@ def read_text_file(file_path: str) -> str: result = chardet.detect(raw_data) encoding = result["encoding"] + if encoding in ["Windows-1252", "Windows-1254", "MacRoman"]: + encoding = "utf-8" + with open(file_path, "r", encoding=encoding) as f: return f.read() diff --git a/src/backend/base/langflow/components/vectorstores/Couchbase.py b/src/backend/base/langflow/components/vectorstores/Couchbase.py index f99ac7d40..ffc17f1b6 100644 --- a/src/backend/base/langflow/components/vectorstores/Couchbase.py +++ b/src/backend/base/langflow/components/vectorstores/Couchbase.py @@ -1,18 +1,12 @@ +from datetime import timedelta from typing import List, Optional, Union -from langchain_community.vectorstores import CouchbaseVectorStore +from langchain_core.retrievers import BaseRetriever from langflow.custom import CustomComponent from langflow.field_typing import Embeddings, VectorStore from langflow.schema import Record -from datetime import timedelta - -from couchbase.auth import PasswordAuthenticator # type: ignore -from couchbase.cluster import Cluster # type: ignore -from couchbase.options import ClusterOptions # type: ignore -from langchain_core.retrievers import BaseRetriever - class CouchbaseComponent(CustomComponent): display_name = "Couchbase" @@ -54,6 +48,16 @@ class CouchbaseComponent(CustomComponent): couchbase_username: str = "", couchbase_password: str = "", ) -> Union[VectorStore, BaseRetriever]: + try: + from couchbase.auth import PasswordAuthenticator # type: ignore + from couchbase.cluster import Cluster # type: ignore + from couchbase.options import ClusterOptions # type: ignore + from langchain_community.vectorstores import CouchbaseVectorStore + except ImportError as e: + raise ImportError( + "Failed to import Couchbase dependencies. Install it using `pip install langflow[couchbase] --pre`" + ) from e + try: auth = PasswordAuthenticator(couchbase_username, couchbase_password) options = ClusterOptions(auth) 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 bbf59c8b1..736edd7dc 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 @@ -81,7 +81,10 @@ "fileTypes": [], "file_path": "", "password": false, - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -89,7 +92,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "sender_name": { "type": "str", @@ -109,7 +114,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "session_id": { "type": "str", @@ -128,13 +135,20 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "_type": "CustomComponent" }, "description": "Get chat inputs from the Playground.", "icon": "ChatInput", - "base_classes": ["Text", "str", "object", "Record"], + "base_classes": [ + "Text", + "str", + "object", + "Record" + ], "display_name": "Chat Input", "documentation": "", "custom_fields": { @@ -144,7 +158,10 @@ "session_id": null, "return_record": null }, - "output_types": ["Text", "Record"], + "output_types": [ + "Text", + "Record" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -181,7 +198,10 @@ "name": "input_value", "display_name": "Value", "advanced": false, - "input_types": ["Record", "Text"], + "input_types": [ + "Record", + "Text" + ], "dynamic": false, "info": "Text or Record to be passed as output.", "load_from_db": false, @@ -223,20 +243,28 @@ "info": "Template to convert Record to Text. If left empty, it will be dynamically set to the Record's text key.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "_type": "CustomComponent" }, "description": "Display a text output in the Playground.", "icon": "type", - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "display_name": "Extracted Chunks", "documentation": "", "custom_fields": { "input_value": null, "record_template": null }, - "output_types": ["Text"], + "output_types": [ + "Text" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -282,7 +310,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "chunk_size": { "type": "int", @@ -394,7 +424,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "disallowed_special": { "type": "str", @@ -403,7 +435,9 @@ "list": false, "show": true, "multiline": false, - "value": ["all"], + "value": [ + "all" + ], "fileTypes": [], "file_path": "", "password": false, @@ -414,7 +448,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "embedding_ctx_length": { "type": "int", @@ -477,7 +513,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "model_kwargs": { "type": "NestedDict", @@ -515,7 +553,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_key": { "type": "str", @@ -534,7 +574,9 @@ "info": "", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "OPENAI_API_KEY" }, "openai_api_type": { @@ -554,7 +596,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_version": { "type": "str", @@ -573,7 +617,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_organization": { "type": "str", @@ -592,7 +638,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_proxy": { "type": "str", @@ -611,7 +659,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "request_timeout": { "type": "float", @@ -711,12 +761,16 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "_type": "CustomComponent" }, "description": "Generate embeddings using OpenAI models.", - "base_classes": ["Embeddings"], + "base_classes": [ + "Embeddings" + ], "display_name": "OpenAI Embeddings", "documentation": "", "custom_fields": { @@ -743,7 +797,9 @@ "tiktoken_enable": null, "tiktoken_model_name": null }, - "output_types": ["Embeddings"], + "output_types": [ + "Embeddings" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -784,7 +840,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "code": { "type": "code", @@ -867,7 +925,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_base": { "type": "str", @@ -886,7 +946,9 @@ "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.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_key": { "type": "str", @@ -905,7 +967,9 @@ "info": "The OpenAI API Key to use for the OpenAI model.", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "OPENAI_API_KEY" }, "stream": { @@ -944,7 +1008,9 @@ "info": "System message to pass to the model.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "temperature": { "type": "float", @@ -975,7 +1041,11 @@ }, "description": "Generates text using OpenAI LLMs.", "icon": "OpenAI", - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "display_name": "OpenAI", "documentation": "", "custom_fields": { @@ -989,7 +1059,9 @@ "stream": null, "system_message": null }, - "output_types": ["Text"], + "output_types": [ + "Text" + ], "field_formatters": {}, "frozen": false, "field_order": [ @@ -1059,7 +1131,9 @@ "name": "template", "display_name": "Template", "advanced": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "dynamic": false, "info": "", "load_from_db": false, @@ -1124,14 +1198,23 @@ "is_input": null, "is_output": null, "is_composition": null, - "base_classes": ["object", "Text", "str"], + "base_classes": [ + "object", + "Text", + "str" + ], "name": "", "display_name": "Prompt", "documentation": "", "custom_fields": { - "template": ["context", "question"] + "template": [ + "context", + "question" + ] }, - "output_types": ["Text"], + "output_types": [ + "Text" + ], "full_path": null, "field_formatters": {}, "frozen": false, @@ -1194,7 +1277,9 @@ "name": "input_value", "display_name": "Message", "advanced": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "dynamic": false, "info": "", "load_from_db": false, @@ -1218,7 +1303,9 @@ "info": "In case of Message being a Record, this template will be used to convert it to text.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "return_record": { "type": "bool", @@ -1250,7 +1337,10 @@ "fileTypes": [], "file_path": "", "password": false, - "options": ["Machine", "User"], + "options": [ + "Machine", + "User" + ], "name": "sender", "display_name": "Sender Type", "advanced": true, @@ -1258,7 +1348,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "sender_name": { "type": "str", @@ -1278,7 +1370,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "session_id": { "type": "str", @@ -1297,13 +1391,20 @@ "info": "If provided, the message will be stored in the memory.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "_type": "CustomComponent" }, "description": "Display a chat message in the Playground.", "icon": "ChatOutput", - "base_classes": ["object", "Text", "Record", "str"], + "base_classes": [ + "object", + "Text", + "Record", + "str" + ], "display_name": "Chat Output", "documentation": "", "custom_fields": { @@ -1314,7 +1415,10 @@ "return_record": null, "record_template": null }, - "output_types": ["Text", "Record"], + "output_types": [ + "Text", + "Record" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1421,14 +1525,18 @@ }, "description": "A generic file loader.", "icon": "file-text", - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "display_name": "File", "documentation": "", "custom_fields": { "path": null, "silent_errors": null }, - "output_types": ["Record"], + "output_types": [ + "Record" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1469,7 +1577,10 @@ "name": "inputs", "display_name": "Input", "advanced": false, - "input_types": ["Document", "Record"], + "input_types": [ + "Document", + "Record" + ], "dynamic": false, "info": "The texts to split.", "load_from_db": false, @@ -1548,13 +1659,19 @@ "info": "The characters to split on.\nIf left empty defaults to [\"\\n\\n\", \"\\n\", \" \", \"\"].", "load_from_db": false, "title_case": false, - "input_types": ["Text"], - "value": [""] + "input_types": [ + "Text" + ], + "value": [ + "" + ] }, "_type": "CustomComponent" }, "description": "Split text into chunks of a specified length.", - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "display_name": "Recursive Character Text Splitter", "documentation": "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter", "custom_fields": { @@ -1563,7 +1680,9 @@ "chunk_size": null, "chunk_overlap": null }, - "output_types": ["Record"], + "output_types": [ + "Record" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -1626,7 +1745,9 @@ "info": "Input value to search", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "api_endpoint": { "type": "str", @@ -1645,7 +1766,9 @@ "info": "API endpoint URL for the Astra DB service.", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "ASTRA_DB_API_ENDPOINT" }, "batch_size": { @@ -1773,7 +1896,9 @@ "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "langflow" }, "metadata_indexing_exclude": { @@ -1793,7 +1918,9 @@ "info": "Optional list of metadata fields to exclude from the indexing.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "metadata_indexing_include": { "type": "str", @@ -1812,7 +1939,9 @@ "info": "Optional list of metadata fields to include in the indexing.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "metric": { "type": "str", @@ -1831,7 +1960,9 @@ "info": "Optional distance metric for vector comparisons in the vector store.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "namespace": { "type": "str", @@ -1850,7 +1981,9 @@ "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "number_of_results": { "type": "int", @@ -1901,7 +2034,10 @@ "fileTypes": [], "file_path": "", "password": false, - "options": ["Similarity", "MMR"], + "options": [ + "Similarity", + "MMR" + ], "name": "search_type", "display_name": "Search Type", "advanced": false, @@ -1909,7 +2045,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "setup_mode": { "type": "str", @@ -1922,7 +2060,11 @@ "fileTypes": [], "file_path": "", "password": false, - "options": ["Sync", "Async", "Off"], + "options": [ + "Sync", + "Async", + "Off" + ], "name": "setup_mode", "display_name": "Setup Mode", "advanced": true, @@ -1930,7 +2072,9 @@ "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "token": { "type": "str", @@ -1949,14 +2093,18 @@ "info": "Authentication token for accessing Astra DB.", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "ASTRA_DB_APPLICATION_TOKEN" }, "_type": "CustomComponent" }, "description": "Searches an existing Astra DB Vector Store.", "icon": "AstraDB", - "base_classes": ["Record"], + "base_classes": [ + "Record" + ], "display_name": "Astra DB Search", "documentation": "", "custom_fields": { @@ -1979,7 +2127,9 @@ "metadata_indexing_exclude": null, "collection_indexing_policy": null }, - "output_types": ["Record"], + "output_types": [ + "Record" + ], "field_formatters": {}, "frozen": false, "field_order": [ @@ -2066,7 +2216,9 @@ "info": "API endpoint URL for the Astra DB service.", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "ASTRA_DB_API_ENDPOINT" }, "batch_size": { @@ -2148,7 +2300,7 @@ "list": false, "show": true, "multiline": true, - "value": "from typing import List, Optional, Union\nfrom langchain_astradb import AstraDBVectorStore\nfrom langchain_astradb.utils.astradb import SetupMode\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\nfrom langchain_core.retrievers import BaseRetriever\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> Union[VectorStore, BaseRetriever]:\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", + "value": "from typing import List, Optional, Union\n\nfrom langflow.custom import CustomComponent\nfrom langflow.field_typing import Embeddings, VectorStore\nfrom langflow.schema import Record\nfrom langchain_core.retrievers import BaseRetriever\n\n\nclass AstraDBVectorStoreComponent(CustomComponent):\n display_name = \"Astra DB\"\n description = \"Builds or loads an Astra DB Vector Store.\"\n icon = \"AstraDB\"\n field_order = [\"token\", \"api_endpoint\", \"collection_name\", \"inputs\", \"embedding\"]\n\n def build_config(self):\n return {\n \"inputs\": {\n \"display_name\": \"Inputs\",\n \"info\": \"Optional list of records to be processed and stored in the vector store.\",\n },\n \"embedding\": {\"display_name\": \"Embedding\", \"info\": \"Embedding to use\"},\n \"collection_name\": {\n \"display_name\": \"Collection Name\",\n \"info\": \"The name of the collection within Astra DB where the vectors will be stored.\",\n },\n \"token\": {\n \"display_name\": \"Token\",\n \"info\": \"Authentication token for accessing Astra DB.\",\n \"password\": True,\n },\n \"api_endpoint\": {\n \"display_name\": \"API Endpoint\",\n \"info\": \"API endpoint URL for the Astra DB service.\",\n },\n \"namespace\": {\n \"display_name\": \"Namespace\",\n \"info\": \"Optional namespace within Astra DB to use for the collection.\",\n \"advanced\": True,\n },\n \"metric\": {\n \"display_name\": \"Metric\",\n \"info\": \"Optional distance metric for vector comparisons in the vector store.\",\n \"advanced\": True,\n },\n \"batch_size\": {\n \"display_name\": \"Batch Size\",\n \"info\": \"Optional number of records to process in a single batch.\",\n \"advanced\": True,\n },\n \"bulk_insert_batch_concurrency\": {\n \"display_name\": \"Bulk Insert Batch Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations.\",\n \"advanced\": True,\n },\n \"bulk_insert_overwrite_concurrency\": {\n \"display_name\": \"Bulk Insert Overwrite Concurrency\",\n \"info\": \"Optional concurrency level for bulk insert operations that overwrite existing records.\",\n \"advanced\": True,\n },\n \"bulk_delete_concurrency\": {\n \"display_name\": \"Bulk Delete Concurrency\",\n \"info\": \"Optional concurrency level for bulk delete operations.\",\n \"advanced\": True,\n },\n \"setup_mode\": {\n \"display_name\": \"Setup Mode\",\n \"info\": \"Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.\",\n \"options\": [\"Sync\", \"Async\", \"Off\"],\n \"advanced\": True,\n },\n \"pre_delete_collection\": {\n \"display_name\": \"Pre Delete Collection\",\n \"info\": \"Boolean flag to determine whether to delete the collection before creating a new one.\",\n \"advanced\": True,\n },\n \"metadata_indexing_include\": {\n \"display_name\": \"Metadata Indexing Include\",\n \"info\": \"Optional list of metadata fields to include in the indexing.\",\n \"advanced\": True,\n },\n \"metadata_indexing_exclude\": {\n \"display_name\": \"Metadata Indexing Exclude\",\n \"info\": \"Optional list of metadata fields to exclude from the indexing.\",\n \"advanced\": True,\n },\n \"collection_indexing_policy\": {\n \"display_name\": \"Collection Indexing Policy\",\n \"info\": \"Optional dictionary defining the indexing policy for the collection.\",\n \"advanced\": True,\n },\n }\n\n def build(\n self,\n embedding: Embeddings,\n token: str,\n api_endpoint: str,\n collection_name: str,\n inputs: Optional[List[Record]] = None,\n namespace: Optional[str] = None,\n metric: Optional[str] = None,\n batch_size: Optional[int] = None,\n bulk_insert_batch_concurrency: Optional[int] = None,\n bulk_insert_overwrite_concurrency: Optional[int] = None,\n bulk_delete_concurrency: Optional[int] = None,\n setup_mode: str = \"Sync\",\n pre_delete_collection: bool = False,\n metadata_indexing_include: Optional[List[str]] = None,\n metadata_indexing_exclude: Optional[List[str]] = None,\n collection_indexing_policy: Optional[dict] = None,\n ) -> Union[VectorStore, BaseRetriever]:\n try:\n from langchain_astradb import AstraDBVectorStore\n from langchain_astradb.utils.astradb import SetupMode\n except ImportError:\n raise ImportError(\n \"Could not import langchain Astra DB integration package. \"\n \"Please install it with `pip install langchain-astradb`.\"\n )\n\n try:\n setup_mode_value = SetupMode[setup_mode.upper()]\n except KeyError:\n raise ValueError(f\"Invalid setup mode: {setup_mode}\")\n if inputs:\n documents = [_input.to_lc_document() for _input in inputs]\n\n vector_store = AstraDBVectorStore.from_documents(\n documents=documents,\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n else:\n vector_store = AstraDBVectorStore(\n embedding=embedding,\n collection_name=collection_name,\n token=token,\n api_endpoint=api_endpoint,\n namespace=namespace,\n metric=metric,\n batch_size=batch_size,\n bulk_insert_batch_concurrency=bulk_insert_batch_concurrency,\n bulk_insert_overwrite_concurrency=bulk_insert_overwrite_concurrency,\n bulk_delete_concurrency=bulk_delete_concurrency,\n setup_mode=setup_mode_value,\n pre_delete_collection=pre_delete_collection,\n metadata_indexing_include=metadata_indexing_include,\n metadata_indexing_exclude=metadata_indexing_exclude,\n collection_indexing_policy=collection_indexing_policy,\n )\n\n return vector_store\n", "fileTypes": [], "file_path": "", "password": false, @@ -2194,7 +2346,9 @@ "info": "The name of the collection within Astra DB where the vectors will be stored.", "load_from_db": false, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "langflow" }, "metadata_indexing_exclude": { @@ -2214,7 +2368,9 @@ "info": "Optional list of metadata fields to exclude from the indexing.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "metadata_indexing_include": { "type": "str", @@ -2233,7 +2389,9 @@ "info": "Optional list of metadata fields to include in the indexing.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "metric": { "type": "str", @@ -2252,7 +2410,9 @@ "info": "Optional distance metric for vector comparisons in the vector store.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "namespace": { "type": "str", @@ -2271,7 +2431,9 @@ "info": "Optional namespace within Astra DB to use for the collection.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "pre_delete_collection": { "type": "bool", @@ -2303,7 +2465,11 @@ "fileTypes": [], "file_path": "", "password": false, - "options": ["Sync", "Async", "Off"], + "options": [ + "Sync", + "Async", + "Off" + ], "name": "setup_mode", "display_name": "Setup Mode", "advanced": true, @@ -2311,7 +2477,9 @@ "info": "Configuration mode for setting up the vector store, with options like “Sync”, “Async”, or “Off”.", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "token": { "type": "str", @@ -2330,14 +2498,18 @@ "info": "Authentication token for accessing Astra DB.", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "ASTRA_DB_APPLICATION_TOKEN" }, "_type": "CustomComponent" }, "description": "Builds or loads an Astra DB Vector Store.", "icon": "AstraDB", - "base_classes": ["VectorStore"], + "base_classes": [ + "VectorStore" + ], "display_name": "Astra DB", "documentation": "", "custom_fields": { @@ -2358,7 +2530,9 @@ "metadata_indexing_exclude": null, "collection_indexing_policy": null }, - "output_types": ["VectorStore"], + "output_types": [ + "VectorStore" + ], "field_formatters": {}, "frozen": false, "field_order": [ @@ -2410,7 +2584,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "chunk_size": { "type": "int", @@ -2522,7 +2698,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "disallowed_special": { "type": "str", @@ -2531,7 +2709,9 @@ "list": false, "show": true, "multiline": false, - "value": ["all"], + "value": [ + "all" + ], "fileTypes": [], "file_path": "", "password": false, @@ -2542,7 +2722,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "embedding_ctx_length": { "type": "int", @@ -2605,7 +2787,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "model_kwargs": { "type": "NestedDict", @@ -2643,7 +2827,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_key": { "type": "str", @@ -2662,7 +2848,9 @@ "info": "", "load_from_db": true, "title_case": false, - "input_types": ["Text"], + "input_types": [ + "Text" + ], "value": "OPENAI_API_KEY" }, "openai_api_type": { @@ -2682,7 +2870,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_api_version": { "type": "str", @@ -2701,7 +2891,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_organization": { "type": "str", @@ -2720,7 +2912,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "openai_proxy": { "type": "str", @@ -2739,7 +2933,9 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "request_timeout": { "type": "float", @@ -2839,12 +3035,16 @@ "info": "", "load_from_db": false, "title_case": false, - "input_types": ["Text"] + "input_types": [ + "Text" + ] }, "_type": "CustomComponent" }, "description": "Generate embeddings using OpenAI models.", - "base_classes": ["Embeddings"], + "base_classes": [ + "Embeddings" + ], "display_name": "OpenAI Embeddings", "documentation": "", "custom_fields": { @@ -2871,7 +3071,9 @@ "tiktoken_enable": null, "tiktoken_model_name": null }, - "output_types": ["Embeddings"], + "output_types": [ + "Embeddings" + ], "field_formatters": {}, "frozen": false, "field_order": [], @@ -2900,11 +3102,20 @@ "targetHandle": { "fieldName": "context", "id": "Prompt-xeI6K", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "TextOutput", "id": "TextOutput-BDknO" } @@ -2925,11 +3136,21 @@ "targetHandle": { "fieldName": "question", "id": "Prompt-xeI6K", - "inputTypes": ["Document", "BaseOutputParser", "Record", "Text"], + "inputTypes": [ + "Document", + "BaseOutputParser", + "Record", + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["Text", "str", "object", "Record"], + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], "dataType": "ChatInput", "id": "ChatInput-yxMKE" } @@ -2950,11 +3171,17 @@ "targetHandle": { "fieldName": "input_value", "id": "OpenAIModel-EjXlN", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "Prompt", "id": "Prompt-xeI6K" } @@ -2975,11 +3202,17 @@ "targetHandle": { "fieldName": "input_value", "id": "ChatOutput-Q39I8", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["object", "Text", "str"], + "baseClasses": [ + "object", + "Text", + "str" + ], "dataType": "OpenAIModel", "id": "OpenAIModel-EjXlN" } @@ -3000,11 +3233,16 @@ "targetHandle": { "fieldName": "inputs", "id": "RecursiveCharacterTextSplitter-tR9QM", - "inputTypes": ["Document", "Record"], + "inputTypes": [ + "Document", + "Record" + ], "type": "Document" }, "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "File", "id": "File-t0a6a" } @@ -3028,7 +3266,9 @@ "type": "Embeddings" }, "sourceHandle": { - "baseClasses": ["Embeddings"], + "baseClasses": [ + "Embeddings" + ], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-ZlOk1" } @@ -3048,11 +3288,18 @@ "targetHandle": { "fieldName": "input_value", "id": "AstraDBSearch-41nRz", - "inputTypes": ["Text"], + "inputTypes": [ + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["Text", "str", "object", "Record"], + "baseClasses": [ + "Text", + "str", + "object", + "Record" + ], "dataType": "ChatInput", "id": "ChatInput-yxMKE" } @@ -3076,7 +3323,9 @@ "type": "Record" }, "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "RecursiveCharacterTextSplitter", "id": "RecursiveCharacterTextSplitter-tR9QM" } @@ -3101,7 +3350,9 @@ "type": "Embeddings" }, "sourceHandle": { - "baseClasses": ["Embeddings"], + "baseClasses": [ + "Embeddings" + ], "dataType": "OpenAIEmbeddings", "id": "OpenAIEmbeddings-9TPjc" } @@ -3122,11 +3373,16 @@ "targetHandle": { "fieldName": "input_value", "id": "TextOutput-BDknO", - "inputTypes": ["Record", "Text"], + "inputTypes": [ + "Record", + "Text" + ], "type": "str" }, "sourceHandle": { - "baseClasses": ["Record"], + "baseClasses": [ + "Record" + ], "dataType": "AstraDBSearch", "id": "AstraDBSearch-41nRz" } @@ -3148,4 +3404,4 @@ "name": "Vector Store RAG", "last_tested_version": "1.0.0a0", "is_component": false -} +} \ No newline at end of file diff --git a/src/backend/base/langflow/services/monitor/service.py b/src/backend/base/langflow/services/monitor/service.py index 805a5e6eb..31d63b0b7 100644 --- a/src/backend/base/langflow/services/monitor/service.py +++ b/src/backend/base/langflow/services/monitor/service.py @@ -112,7 +112,7 @@ class MonitorService(Service): def delete_messages(self, message_ids: Union[List[int], str]): if isinstance(message_ids, list): # If message_ids is a list, join the string representations of the integers - ids_str = ','.join(map(str, message_ids)) + ids_str = ",".join(map(str, message_ids)) elif isinstance(message_ids, str): # If message_ids is already a string, use it directly ids_str = message_ids diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 75fbdcd6a..a3e029b17 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -517,13 +517,13 @@ test-randomorder = ["pytest-randomly"] [[package]] name = "dataclasses-json" -version = "0.6.6" +version = "0.6.7" description = "Easily serialize dataclasses to and from JSON." optional = false python-versions = "<4.0,>=3.7" files = [ - {file = "dataclasses_json-0.6.6-py3-none-any.whl", hash = "sha256:e54c5c87497741ad454070ba0ed411523d46beb5da102e221efb873801b0ba85"}, - {file = "dataclasses_json-0.6.6.tar.gz", hash = "sha256:0c09827d26fffda27f1be2fed7a7a01a29c5ddcd2eb6393ad5ebf9d77e9deae8"}, + {file = "dataclasses_json-0.6.7-py3-none-any.whl", hash = "sha256:0dbf33f26c8d5305befd61b39d2b3414e8a407bedc2834dea9b8d642666fb40a"}, + {file = "dataclasses_json-0.6.7.tar.gz", hash = "sha256:b6b3e528266ea45b9535223bc53ca645f5208833c29229e847b3f26a1cc55fc0"}, ] [package.dependencies] @@ -1148,13 +1148,13 @@ jsonpointer = ">=1.9" [[package]] name = "jsonpointer" -version = "2.4" +version = "3.0.0" description = "Identify specific nodes in a JSON document (RFC 6901)" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +python-versions = ">=3.7" files = [ - {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, - {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, + {file = "jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942"}, + {file = "jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef"}, ] [[package]] @@ -1260,13 +1260,13 @@ extended-testing = ["beautifulsoup4 (>=4.12.3,<5.0.0)", "lxml (>=4.9.3,<6.0)"] [[package]] name = "langchainhub" -version = "0.1.17" +version = "0.1.18" description = "The LangChain Hub API client" optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langchainhub-0.1.17-py3-none-any.whl", hash = "sha256:4c609b3948252c71670f0d98f73413b515cfd2f6701a7b40ce959203e6133e04"}, - {file = "langchainhub-0.1.17.tar.gz", hash = "sha256:af7df0cb1cebc7a6e0864e8632ae48ecad39ed96568f699c78657b9d04e50b46"}, + {file = "langchainhub-0.1.18-py3-none-any.whl", hash = "sha256:11501f15e7f34715ecc8892587daa35c6f2a3005e1f2926c9bcabd31fc2c100c"}, + {file = "langchainhub-0.1.18.tar.gz", hash = "sha256:f2d0d8bf3abe4ca5e70511d8220bdc9ccea28d5267bcfd0e5ef9c53bd5bd3bad"}, ] [package.dependencies] @@ -1275,13 +1275,13 @@ types-requests = ">=2.31.0.2,<3.0.0.0" [[package]] name = "langsmith" -version = "0.1.75" +version = "0.1.76" description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." optional = false python-versions = "<4.0,>=3.8.1" files = [ - {file = "langsmith-0.1.75-py3-none-any.whl", hash = "sha256:d08b08dd6b3fa4da170377f95123d77122ef4c52999d10fff4ae08ff70d07aed"}, - {file = "langsmith-0.1.75.tar.gz", hash = "sha256:61274e144ea94c297dd78ce03e6dfae18459fe9bd8ab5094d61a0c4816561279"}, + {file = "langsmith-0.1.76-py3-none-any.whl", hash = "sha256:4b8cb14f2233d9673ce9e6e3d545359946d9690a2c1457ab01e7459ec97b964e"}, + {file = "langsmith-0.1.76.tar.gz", hash = "sha256:5829f997495c0f9a39f91fe0a57e0cb702e8642e6948945f5bb9f46337db7732"}, ] [package.dependencies] @@ -2713,13 +2713,13 @@ urllib3 = ">=2" [[package]] name = "typing-extensions" -version = "4.12.1" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.12.1-py3-none-any.whl", hash = "sha256:6024b58b69089e5a89c347397254e35f1bf02a907728ec7fee9bf0fe837d203a"}, - {file = "typing_extensions-4.12.1.tar.gz", hash = "sha256:915f5e35ff76f56588223f15fdd5938f9a1cf9195c0de25130c627e4d597f6d1"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index b175fbcf5..291a8133a 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.60" +version = "0.0.61" description = "A Python package with a built-in web application" authors = ["Langflow "] maintainers = [ From 11b5aad3bd8e579af8064311cf3c7c12ad59ce28 Mon Sep 17 00:00:00 2001 From: "YAMON.IO" Date: Tue, 11 Jun 2024 21:42:49 +0900 Subject: [PATCH 2/2] add PythonCodeStructuredTool (#1747) * Create PythonStructuredTool This draft involves receiving two 'Code' types as inputs and creating a structured tool. * Delete src/backend/base/langflow/components/experimental/PythonStructuredTool * Create PythonCodeStructuredTool.py --- .../tools/PythonCodeStructuredTool.py | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 src/backend/base/langflow/components/tools/PythonCodeStructuredTool.py diff --git a/src/backend/base/langflow/components/tools/PythonCodeStructuredTool.py b/src/backend/base/langflow/components/tools/PythonCodeStructuredTool.py new file mode 100644 index 000000000..7de988d24 --- /dev/null +++ b/src/backend/base/langflow/components/tools/PythonCodeStructuredTool.py @@ -0,0 +1,91 @@ +from typing import Any, Dict, List, Callable +import ast +from langchain.agents import Tool +from langchain.tools import StructuredTool +from langflow.interface.custom.custom_component import CustomComponent +from langflow.schema.dotdict import dotdict +from langchain.pydantic_v1 import BaseModel, Field + + +class PythonCodeStructuredTool(CustomComponent): + display_name = "PythonCodeTool" + description = "structuredtool dataclass code to tool" + documentation = "https://python.langchain.com/docs/modules/tools/custom_tools/#structuredtool-dataclass" + icon = "🐍" + field_order = ["name", "description", "tool_code", + "return_direct", "tool_function", "tool_class"] + + def build_config(self) -> Dict[str, Any]: + return { + "tool_code": { + "display_name": "Tool Code", + "info": "Enter the dataclass code.", + "placeholder": "def my_function(args):\n pass", + "multiline": True, + "refresh_button": True, + }, + "name": { + "display_name": "Tool Name", + "info": "Enter the name of the tool.", + }, + "description": { + "display_name": "Description", + "info": "Provide a brief description of what the tool does.", + }, + "return_direct": { + "display_name": "Return Directly", + "info": "Should the tool return the function output directly?", + }, + "tool_function": { + "display_name": "Tool Function", + "info": "Select the function for additional expressions.", + "options": [], + "refresh_button": True, + }, + "tool_class": { + "display_name": "Tool Class", + "info": "Select the class for additional expressions.", + "options": [], + "refresh_button": True, + "required": False, + }, + } + + def parse_source_name(self, code: str) -> Dict: + parsed_code = ast.parse(code) + class_names = [ + node.name for node in parsed_code.body if isinstance(node, ast.ClassDef)] + function_names = [ + node.name for node in parsed_code.body if isinstance(node, ast.FunctionDef)] + return {"class": class_names, "function": function_names} + + def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None) -> dotdict: + if field_name == "tool_code" or field_name == "tool_function" or field_name == "tool_class": + try: + names = self.parse_source_name(build_config.tool_code.value) + build_config.tool_class.options = names["class"] + build_config.tool_function.options = names["function"] + except Exception as e: + self.status = f"Failed to extract class names: {str(e)}" + build_config.tool_class.options = ["Failed to parse", str(e)] + build_config.tool_function.options = [] + return build_config + + async def build(self, tool_code: Code, name: str, description: str, tool_function: List[str], return_direct: bool, tool_class: List[str] = None) -> Tool: + local_namespace = {} + exec(tool_code, globals(), local_namespace) + + func = local_namespace[tool_function] + _class = None + + if tool_class: + _class = local_namespace[tool_class] + + tool = StructuredTool.from_function( + func=func, + args_schema=_class, + name=name, + description=description, + return_direct=return_direct + ) + return tool