diff --git a/src/backend/base/langflow/components/vectorstores/AstraDB.py b/src/backend/base/langflow/components/vectorstores/AstraDB.py index 2be70ac80..1ce2819cc 100644 --- a/src/backend/base/langflow/components/vectorstores/AstraDB.py +++ b/src/backend/base/langflow/components/vectorstores/AstraDB.py @@ -1,7 +1,16 @@ from loguru import logger from langflow.base.vectorstores.model import LCVectorStoreComponent -from langflow.io import BoolInput, DropdownInput, HandleInput, IntInput, MultilineInput, SecretStrInput, StrInput +from langflow.io import ( + BoolInput, + DropdownInput, + HandleInput, + IntInput, + MultilineInput, + SecretStrInput, + StrInput, + DataInput, +) from langflow.schema import Data @@ -29,10 +38,9 @@ class AstraVectorStoreComponent(LCVectorStoreComponent): info="API endpoint URL for the Astra DB service.", value="ASTRA_DB_API_ENDPOINT", ), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), HandleInput( diff --git a/src/backend/base/langflow/components/vectorstores/Cassandra.py b/src/backend/base/langflow/components/vectorstores/Cassandra.py index 4446feabe..d4f215cd3 100644 --- a/src/backend/base/langflow/components/vectorstores/Cassandra.py +++ b/src/backend/base/langflow/components/vectorstores/Cassandra.py @@ -1,15 +1,23 @@ from typing import List from langchain_community.vectorstores import Cassandra -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, DropdownInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import ( + BoolInput, + DropdownInput, + HandleInput, + IntInput, + SecretStrInput, + TextInput, + DataInput, + MultilineInput, +) from langflow.schema import Data -class CassandraVectorStoreComponent(Component): +class CassandraVectorStoreComponent(LCVectorStoreComponent): display_name = "Cassandra" description = "Cassandra Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/cassandra" @@ -22,14 +30,14 @@ class CassandraVectorStoreComponent(Component): info="Authentication token for accessing Cassandra on Astra DB.", required=True, ), - StrInput(name="database_id", display_name="Database ID", info="The Astra database ID.", required=True), - StrInput( + TextInput(name="database_id", display_name="Database ID", info="The Astra database ID.", required=True), + TextInput( name="table_name", display_name="Table Name", info="The name of the table where vectors will be stored.", required=True, ), - StrInput( + TextInput( name="keyspace", display_name="Keyspace", info="Optional key space within Astra DB. The keyspace should already be created.", @@ -48,7 +56,7 @@ class CassandraVectorStoreComponent(Component): value=16, advanced=True, ), - StrInput( + TextInput( name="body_index_options", display_name="Body Index Options", info="Optional options used to create the body index.", @@ -63,10 +71,9 @@ class CassandraVectorStoreComponent(Component): advanced=True, ), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -74,7 +81,7 @@ class CassandraVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -84,17 +91,6 @@ class CassandraVectorStoreComponent(Component): ), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=Cassandra), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> Cassandra: return self._build_cassandra() diff --git a/src/backend/base/langflow/components/vectorstores/Chroma.py b/src/backend/base/langflow/components/vectorstores/Chroma.py index a8b25a5c0..ae2964ea6 100644 --- a/src/backend/base/langflow/components/vectorstores/Chroma.py +++ b/src/backend/base/langflow/components/vectorstores/Chroma.py @@ -7,7 +7,7 @@ from loguru import logger from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.base.vectorstores.utils import chroma_collection_to_data -from langflow.io import BoolInput, DataInput, DropdownInput, HandleInput, IntInput, StrInput, TextInput +from langflow.io import BoolInput, DataInput, DropdownInput, HandleInput, IntInput, StrInput, MultilineInput from langflow.schema import Data if TYPE_CHECKING: @@ -34,13 +34,14 @@ class ChromaVectorStoreComponent(LCVectorStoreComponent): name="persist_directory", display_name="Persist Directory", ), - TextInput( + MultilineInput( name="search_query", display_name="Search Query", ), DataInput( name="ingest_data", display_name="Ingest Data", + is_list=True, ), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), StrInput( @@ -96,7 +97,7 @@ class ChromaVectorStoreComponent(LCVectorStoreComponent): ), ] - def build_vector_store(self) -> "Chroma": + def build_vector_store(self) -> Chroma: """ Builds the Chroma object. """ diff --git a/src/backend/base/langflow/components/vectorstores/Couchbase.py b/src/backend/base/langflow/components/vectorstores/Couchbase.py index deac2b478..56a01d0db 100644 --- a/src/backend/base/langflow/components/vectorstores/Couchbase.py +++ b/src/backend/base/langflow/components/vectorstores/Couchbase.py @@ -2,15 +2,14 @@ from datetime import timedelta from typing import List from langchain_community.vectorstores import CouchbaseVectorStore -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class CouchbaseVectorStoreComponent(Component): +class CouchbaseVectorStoreComponent(LCVectorStoreComponent): display_name = "Couchbase" description = "Couchbase Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/couchbase" @@ -25,10 +24,9 @@ class CouchbaseVectorStoreComponent(Component): StrInput(name="collection_name", display_name="Collection Name", required=True), StrInput(name="index_name", display_name="Index Name", required=True), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -36,7 +34,7 @@ class CouchbaseVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -46,22 +44,6 @@ class CouchbaseVectorStoreComponent(Component): ), ] - outputs = [ - Output( - display_name="Vector Store", - name="vector_store", - method="build_vector_store", - output_type=CouchbaseVectorStore, - ), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> CouchbaseVectorStore: return self._build_couchbase() diff --git a/src/backend/base/langflow/components/vectorstores/FAISS.py b/src/backend/base/langflow/components/vectorstores/FAISS.py index dab0a069c..5a3c4f1c9 100644 --- a/src/backend/base/langflow/components/vectorstores/FAISS.py +++ b/src/backend/base/langflow/components/vectorstores/FAISS.py @@ -6,7 +6,7 @@ from loguru import logger from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.field_typing import Text from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, DataInput, MultilineInput from langflow.schema import Data @@ -32,10 +32,9 @@ class FaissVectorStoreComponent(LCVectorStoreComponent): value="langflow_index", ), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - StrInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -48,9 +47,9 @@ class FaissVectorStoreComponent(LCVectorStoreComponent): display_name="Allow Dangerous Deserialization", info="Set to True to allow loading pickle files from untrusted sources. Only enable this if you trust the source of the data.", advanced=True, - value=False, + value=True, ), - StrInput( + MultilineInput( name="search_input", display_name="Search Input", ), @@ -63,24 +62,6 @@ class FaissVectorStoreComponent(LCVectorStoreComponent): ), ] - outputs = [ - Output( - display_name="Vector Store", - name="vector_store", - method="build_vector_store", - ), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - ), - Output( - display_name="Search Results", - name="search_results", - method="search_documents", - ), - ] - def build_vector_store(self) -> FAISS: """ Builds the FAISS object. @@ -100,19 +81,12 @@ class FaissVectorStoreComponent(LCVectorStoreComponent): faiss = FAISS.from_documents(documents=documents, embedding=self.embedding) faiss.save_local(Text(path), self.index_name) else: - try: - faiss = FAISS.load_local( - folder_path=Text(path), - embeddings=self.embedding, - index_name=self.index_name, - allow_dangerous_deserialization=self.allow_dangerous_deserialization, - ) - except Exception as e: - raise ValueError( - "Failed to load the FAISS index. Make sure the index was created with trusted data. " - "If you trust the data source, you can set `allow_dangerous_deserialization` to `True` " - "in the component's advanced settings to enable deserialization." - ) from e + faiss = FAISS.load_local( + folder_path=Text(path), + embeddings=self.embedding, + index_name=self.index_name, + allow_dangerous_deserialization=self.allow_dangerous_deserialization, + ) return faiss @@ -124,19 +98,12 @@ class FaissVectorStoreComponent(LCVectorStoreComponent): raise ValueError("Folder path is required to load the FAISS index.") path = self.resolve_path(self.folder_path) - try: - vector_store = FAISS.load_local( - folder_path=Text(path), - embeddings=self.embedding, - index_name=self.index_name, - allow_dangerous_deserialization=self.allow_dangerous_deserialization, - ) - except Exception as e: - raise ValueError( - "Failed to load the FAISS index. Make sure the index was created with trusted data. " - "If you trust the data source, you can set `allow_dangerous_deserialization` to `True` " - "in the component's advanced settings to enable deserialization." - ) from e + vector_store = FAISS.load_local( + folder_path=Text(path), + embeddings=self.embedding, + index_name=self.index_name, + allow_dangerous_deserialization=self.allow_dangerous_deserialization, + ) if not vector_store: raise ValueError("Failed to load the FAISS index.") diff --git a/src/backend/base/langflow/components/vectorstores/MongoDBAtlasVector.py b/src/backend/base/langflow/components/vectorstores/MongoDBAtlasVector.py index 68ced0269..ca6bacfc7 100644 --- a/src/backend/base/langflow/components/vectorstores/MongoDBAtlasVector.py +++ b/src/backend/base/langflow/components/vectorstores/MongoDBAtlasVector.py @@ -1,30 +1,28 @@ from typing import List from langchain_community.vectorstores import MongoDBAtlasVectorSearch -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class MongoVectorStoreComponent(Component): +class MongoVectorStoreComponent(LCVectorStoreComponent): display_name = "MongoDB Atlas" description = "MongoDB Atlas Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/mongodb_atlas" icon = "MongoDB" inputs = [ - StrInput(name="mongodb_atlas_cluster_uri", display_name="MongoDB Atlas Cluster URI", required=True), + SecretStrInput(name="mongodb_atlas_cluster_uri", display_name="MongoDB Atlas Cluster URI", required=True), StrInput(name="db_name", display_name="Database Name", required=True), StrInput(name="collection_name", display_name="Collection Name", required=True), StrInput(name="index_name", display_name="Index Name", required=True), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -32,7 +30,7 @@ class MongoVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -42,22 +40,6 @@ class MongoVectorStoreComponent(Component): ), ] - outputs = [ - Output( - display_name="Vector Store", - name="vector_store", - method="build_vector_store", - output_type=MongoDBAtlasVectorSearch, - ), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> MongoDBAtlasVectorSearch: return self._build_mongodb_atlas() @@ -83,12 +65,7 @@ class MongoVectorStoreComponent(Component): if documents: vector_store = MongoDBAtlasVectorSearch.from_documents( - documents=documents, - embedding=self.embedding, - collection=collection, - db_name=self.db_name, - index_name=self.index_name, - mongodb_atlas_cluster_uri=self.mongodb_atlas_cluster_uri, + documents=documents, embedding=self.embedding, collection=collection, index_name=self.index_name ) else: vector_store = MongoDBAtlasVectorSearch( @@ -106,14 +83,31 @@ class MongoVectorStoreComponent(Component): return vector_store def search_documents(self) -> List[Data]: + from typing import Union + from bson import ObjectId + from langchain.schema import Document + import json + vector_store = self._build_mongodb_atlas() - if self.search_input and isinstance(self.search_input, str) and self.search_input.strip(): + class JSONEncoder(json.JSONEncoder): + def default(self, o): + if isinstance(o, Union[ObjectId, Document]): + return str(o) + return super(JSONEncoder, self).default(o) + + if self.search_input and isinstance(self.search_input, str): docs = vector_store.similarity_search( query=self.search_input, k=self.number_of_results, ) - + for index in range(len(docs)): + docs[index].metadata = { + key: str(docs[index].metadata[key]) + if isinstance(docs[index].metadata[key], ObjectId) + else docs[index].metadata[key] + for key in docs[index].metadata + } data = docs_to_data(docs) self.status = data return data diff --git a/src/backend/base/langflow/components/vectorstores/Pinecone.py b/src/backend/base/langflow/components/vectorstores/Pinecone.py index 57d9137b6..155b9b2f0 100644 --- a/src/backend/base/langflow/components/vectorstores/Pinecone.py +++ b/src/backend/base/langflow/components/vectorstores/Pinecone.py @@ -1,15 +1,23 @@ from typing import List -from langchain_core.retrievers import BaseRetriever from langchain_pinecone import Pinecone -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, DropdownInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import ( + BoolInput, + DropdownInput, + HandleInput, + IntInput, + StrInput, + SecretStrInput, + DataInput, + MultilineInput, +) from langflow.schema import Data -class PineconeVectorStoreComponent(Component): +class PineconeVectorStoreComponent(LCVectorStoreComponent): display_name = "Pinecone" description = "Pinecone Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pinecone" @@ -34,18 +42,18 @@ class PineconeVectorStoreComponent(Component): value="text", advanced=True, ), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( name="add_to_vector_store", display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", + value=True, ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -55,17 +63,6 @@ class PineconeVectorStoreComponent(Component): ), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=Pinecone), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> Pinecone: return self._build_pinecone() diff --git a/src/backend/base/langflow/components/vectorstores/Qdrant.py b/src/backend/base/langflow/components/vectorstores/Qdrant.py index f1c25aa57..68c214695 100644 --- a/src/backend/base/langflow/components/vectorstores/Qdrant.py +++ b/src/backend/base/langflow/components/vectorstores/Qdrant.py @@ -1,15 +1,23 @@ from typing import List from langchain_community.vectorstores import Qdrant -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, DropdownInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import ( + BoolInput, + DropdownInput, + HandleInput, + IntInput, + StrInput, + SecretStrInput, + DataInput, + MultilineInput, +) from langflow.schema import Data -class QdrantVectorStoreComponent(Component): +class QdrantVectorStoreComponent(LCVectorStoreComponent): display_name = "Qdrant" description = "Qdrant Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/qdrant" @@ -35,10 +43,9 @@ class QdrantVectorStoreComponent(Component): StrInput(name="content_payload_key", display_name="Content Payload Key", value="page_content", advanced=True), StrInput(name="metadata_payload_key", display_name="Metadata Payload Key", value="metadata", advanced=True), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -46,7 +53,7 @@ class QdrantVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -56,17 +63,6 @@ class QdrantVectorStoreComponent(Component): ), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=Qdrant), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> Qdrant: return self._build_qdrant() @@ -91,7 +87,6 @@ class QdrantVectorStoreComponent(Component): # Remove None values from server_kwargs server_kwargs = {k: v for k, v in server_kwargs.items() if v is not None} - if self.add_to_vector_store: documents = [] for _input in self.vector_store_inputs or []: @@ -101,9 +96,7 @@ class QdrantVectorStoreComponent(Component): documents.append(_input) if documents: - qdrant = Qdrant.from_documents( - documents, embedding=self.embedding, client_kwargs=server_kwargs, **qdrant_kwargs - ) + qdrant = Qdrant.from_documents(documents, embedding=self.embedding, **qdrant_kwargs) else: from qdrant_client import QdrantClient diff --git a/src/backend/base/langflow/components/vectorstores/Redis.py b/src/backend/base/langflow/components/vectorstores/Redis.py index fd7b70678..31927f09f 100644 --- a/src/backend/base/langflow/components/vectorstores/Redis.py +++ b/src/backend/base/langflow/components/vectorstores/Redis.py @@ -1,14 +1,15 @@ -from typing import Optional, cast +from typing import List from langchain_community.vectorstores.redis import Redis -from langchain_core.embeddings import Embeddings -from langflow.custom import CustomComponent -from langflow.field_typing import VectorStore +from langflow.base.vectorstores.model import LCVectorStoreComponent +from langflow.helpers.data import docs_to_data +from langflow.io import HandleInput, IntInput, StrInput, SecretStrInput, MultilineInput, DataInput from langflow.schema import Data +from langchain.text_splitter import CharacterTextSplitter -class RedisVectorStoreComponent(CustomComponent): +class RedisVectorStoreComponent(LCVectorStoreComponent): """ A custom component for implementing a Vector Store using Redis. """ @@ -17,67 +18,77 @@ class RedisVectorStoreComponent(CustomComponent): description: str = "Implementation of Vector Store using Redis" documentation = "https://python.langchain.com/docs/integrations/vectorstores/redis" - def build_config(self): - """ - Builds the configuration for the component. + inputs = [ + SecretStrInput(name="redis_server_url", display_name="Redis Server Connection String", required=True), + StrInput( + name="redis_index_name", + display_name="Redis Index", + ), + StrInput(name="code", display_name="Code", advanced=True), + StrInput( + name="schema", + display_name="Schema", + field_type=[".yaml"], + ), + DataInput( + name="vector_store_inputs", + display_name="Vector Store Inputs", + is_list=True, + ), + MultilineInput(name="search_input", display_name="Search Input"), + IntInput( + name="number_of_results", + display_name="Number of Results", + info="Number of results to return.", + value=4, + advanced=True, + ), + HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), + ] - Returns: - - dict: A dictionary containing the configuration options for the component. - """ - return { - "index_name": {"display_name": "Index Name", "value": "your_index"}, - "code": {"show": False, "display_name": "Code"}, - "inputs": {"display_name": "Input", "input_types": ["Document", "Data"]}, - "embedding": {"display_name": "Embedding"}, - "schema": {"display_name": "Schema", "file_types": [".yaml"]}, - "redis_server_url": { - "display_name": "Redis Server Connection String", - "advanced": False, - }, - "redis_index_name": {"display_name": "Redis Index", "advanced": False}, - } - - def build( - self, - embedding: Embeddings, - redis_server_url: str, - redis_index_name: str, - schema: Optional[str] = None, - inputs: Optional[Data] = None, - ) -> VectorStore: - """ - Builds the Vector Store or BaseRetriever object. - - Args: - - embedding (Embeddings): The embeddings to use for the Vector Store. - - documents (Optional[Document]): The documents to use for the Vector Store. - - redis_index_name (str): The name of the Redis index. - - redis_server_url (str): The URL for the Redis server. - - Returns: - - VectorStore: The Vector Store object. - """ + def build_vector_store(self) -> Redis: documents = [] - for _input in inputs or []: + + for _input in self.vector_store_inputs or []: if isinstance(_input, Data): documents.append(_input.to_lc_document()) else: documents.append(_input) + with open("docuemnts.txt", "w") as f: + f.write(str(documents)) + if not documents: - if schema is None: + if self.schema is None: raise ValueError("If no documents are provided, a schema must be provided.") redis_vs = Redis.from_existing_index( - embedding=embedding, - index_name=redis_index_name, - schema=schema, + embedding=self.embedding, + index_name=self.redis_index_name, + schema=self.schema, key_prefix=None, - redis_url=redis_server_url, + redis_url=self.redis_server_url, ) else: + text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) + docs = text_splitter.split_documents(documents) redis_vs = Redis.from_documents( - documents=documents, # type: ignore - embedding=embedding, - redis_url=redis_server_url, - index_name=redis_index_name, + documents=docs, + embedding=self.embedding, + redis_url=self.redis_server_url, + index_name=self.redis_index_name, ) - return cast(VectorStore, redis_vs) + return redis_vs + + def search_documents(self) -> List[Data]: + vector_store = self._build_redis() + + if self.search_input and isinstance(self.search_input, str) and self.search_input.strip(): + docs = vector_store.similarity_search( + query=self.search_input, + k=self.number_of_results, + ) + + data = docs_to_data(docs) + self.status = data + return data + else: + return [] diff --git a/src/backend/base/langflow/components/vectorstores/SupabaseVectorStore.py b/src/backend/base/langflow/components/vectorstores/SupabaseVectorStore.py index f3b8ef273..f517411c1 100644 --- a/src/backend/base/langflow/components/vectorstores/SupabaseVectorStore.py +++ b/src/backend/base/langflow/components/vectorstores/SupabaseVectorStore.py @@ -1,16 +1,15 @@ from typing import List from langchain_community.vectorstores import SupabaseVectorStore -from langchain_core.retrievers import BaseRetriever from supabase.client import Client, create_client -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import HandleInput, IntInput, Output, StrInput +from langflow.io import HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class SupabaseVectorStoreComponent(Component): +class SupabaseVectorStoreComponent(LCVectorStoreComponent): display_name = "Supabase" description = "Supabase Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/supabase" @@ -18,17 +17,16 @@ class SupabaseVectorStoreComponent(Component): inputs = [ StrInput(name="supabase_url", display_name="Supabase URL", required=True), - StrInput(name="supabase_service_key", display_name="Supabase Service Key", required=True), + SecretStrInput(name="supabase_service_key", display_name="Supabase Service Key", required=True), StrInput(name="table_name", display_name="Table Name", advanced=True), StrInput(name="query_name", display_name="Query Name"), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -38,22 +36,6 @@ class SupabaseVectorStoreComponent(Component): ), ] - outputs = [ - Output( - display_name="Vector Store", - name="vector_store", - method="build_vector_store", - output_type=SupabaseVectorStore, - ), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> SupabaseVectorStore: return self._build_supabase() diff --git a/src/backend/base/langflow/components/vectorstores/Upstash.py b/src/backend/base/langflow/components/vectorstores/Upstash.py index 3793254a6..108bd272f 100644 --- a/src/backend/base/langflow/components/vectorstores/Upstash.py +++ b/src/backend/base/langflow/components/vectorstores/Upstash.py @@ -1,15 +1,14 @@ from typing import List from langchain_community.vectorstores import UpstashVectorStore -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class UpstashVectorStoreComponent(Component): +class UpstashVectorStoreComponent(LCVectorStoreComponent): display_name = "Upstash" description = "Upstash Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/upstash" @@ -17,7 +16,7 @@ class UpstashVectorStoreComponent(Component): inputs = [ StrInput(name="index_url", display_name="Index URL", info="The URL of the Upstash index.", required=True), - StrInput( + SecretStrInput( name="index_token", display_name="Index Token", info="The token for the Upstash index.", required=True ), StrInput( @@ -33,10 +32,9 @@ class UpstashVectorStoreComponent(Component): input_types=["Embeddings"], info="To use Upstash's embeddings, don't provide an embedding.", ), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -44,7 +42,7 @@ class UpstashVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -54,22 +52,6 @@ class UpstashVectorStoreComponent(Component): ), ] - outputs = [ - Output( - display_name="Vector Store", - name="vector_store", - method="build_vector_store", - output_type=UpstashVectorStore, - ), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> UpstashVectorStore: return self._build_upstash() diff --git a/src/backend/base/langflow/components/vectorstores/Vectara.py b/src/backend/base/langflow/components/vectorstores/Vectara.py index 2c454a7b1..a48729eaa 100644 --- a/src/backend/base/langflow/components/vectorstores/Vectara.py +++ b/src/backend/base/langflow/components/vectorstores/Vectara.py @@ -2,15 +2,14 @@ from typing import List from langchain_community.embeddings import FakeEmbeddings from langchain_community.vectorstores import Vectara -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import BoolInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class VectaraVectorStoreComponent(Component): +class VectaraVectorStoreComponent(LCVectorStoreComponent): display_name = "Vectara" description = "Vectara Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/vectara" @@ -20,10 +19,9 @@ class VectaraVectorStoreComponent(Component): StrInput(name="vectara_customer_id", display_name="Vectara Customer ID", required=True), StrInput(name="vectara_corpus_id", display_name="Vectara Corpus ID", required=True), SecretStrInput(name="vectara_api_key", display_name="Vectara API Key", required=True), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -31,7 +29,7 @@ class VectaraVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -41,17 +39,6 @@ class VectaraVectorStoreComponent(Component): ), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=Vectara), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> Vectara: return self._build_vectara() diff --git a/src/backend/base/langflow/components/vectorstores/Weaviate.py b/src/backend/base/langflow/components/vectorstores/Weaviate.py index 26981c04b..42d04494c 100644 --- a/src/backend/base/langflow/components/vectorstores/Weaviate.py +++ b/src/backend/base/langflow/components/vectorstores/Weaviate.py @@ -2,15 +2,14 @@ from typing import List import weaviate # type: ignore from langchain_community.vectorstores import Weaviate -from langchain_core.retrievers import BaseRetriever -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, SecretStrInput, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class WeaviateVectorStoreComponent(Component): +class WeaviateVectorStoreComponent(LCVectorStoreComponent): display_name = "Weaviate" description = "Weaviate Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/weaviate" @@ -22,10 +21,9 @@ class WeaviateVectorStoreComponent(Component): StrInput(name="index_name", display_name="Index Name", required=True), StrInput(name="text_key", display_name="Text Key", value="text", advanced=True), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -33,7 +31,7 @@ class WeaviateVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -44,17 +42,6 @@ class WeaviateVectorStoreComponent(Component): BoolInput(name="search_by_text", display_name="Search By Text", advanced=True), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=Weaviate), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> Weaviate: return self._build_weaviate() diff --git a/src/backend/base/langflow/components/vectorstores/pgvector.py b/src/backend/base/langflow/components/vectorstores/pgvector.py index 48f8ac13c..95808c70c 100644 --- a/src/backend/base/langflow/components/vectorstores/pgvector.py +++ b/src/backend/base/langflow/components/vectorstores/pgvector.py @@ -1,28 +1,26 @@ from typing import List -from langchain.schema import BaseRetriever from langchain_community.vectorstores import PGVector -from langflow.custom import Component +from langflow.base.vectorstores.model import LCVectorStoreComponent from langflow.helpers.data import docs_to_data -from langflow.io import BoolInput, HandleInput, IntInput, Output, StrInput +from langflow.io import BoolInput, HandleInput, IntInput, StrInput, SecretStrInput, DataInput, MultilineInput from langflow.schema import Data -class PGVectorStoreComponent(Component): +class PGVectorStoreComponent(LCVectorStoreComponent): display_name = "PGVector" description = "PGVector Vector Store with search capabilities" documentation = "https://python.langchain.com/docs/modules/data_connection/vectorstores/integrations/pgvector" icon = "PGVector" inputs = [ - StrInput(name="pg_server_url", display_name="PostgreSQL Server Connection String", required=True), + SecretStrInput(name="pg_server_url", display_name="PostgreSQL Server Connection String", required=True), StrInput(name="collection_name", display_name="Table", required=True), HandleInput(name="embedding", display_name="Embedding", input_types=["Embeddings"]), - HandleInput( + DataInput( name="vector_store_inputs", display_name="Vector Store Inputs", - input_types=["Document", "Data"], is_list=True, ), BoolInput( @@ -30,7 +28,7 @@ class PGVectorStoreComponent(Component): display_name="Add to Vector Store", info="If true, the Vector Store Inputs will be added to the Vector Store.", ), - StrInput(name="search_input", display_name="Search Input"), + MultilineInput(name="search_input", display_name="Search Input"), IntInput( name="number_of_results", display_name="Number of Results", @@ -40,17 +38,6 @@ class PGVectorStoreComponent(Component): ), ] - outputs = [ - Output(display_name="Vector Store", name="vector_store", method="build_vector_store", output_type=PGVector), - Output( - display_name="Base Retriever", - name="base_retriever", - method="build_base_retriever", - output_type=BaseRetriever, - ), - Output(display_name="Search Results", name="search_results", method="search_documents"), - ] - def build_vector_store(self) -> PGVector: return self._build_pgvector()