diff --git a/docs/docs/components/vector-stores.mdx b/docs/docs/components/vector-stores.mdx index 66d6685a1..7e21f1021 100644 --- a/docs/docs/components/vector-stores.mdx +++ b/docs/docs/components/vector-stores.mdx @@ -26,7 +26,8 @@ The `Astra DB` initializes a vector store using Astra DB from records. It create - **Collection Indexing Policy:** Indexing policy for the collection. - Ensure you configure the necessary Astra DB token and API endpoint before starting. + Ensure you configure the necessary Astra DB token and API endpoint before + starting. --- @@ -96,6 +97,44 @@ For detailed documentation and integration guides, please refer to the [Chroma C --- +### Couchbase + +`Couchbase` builds a Couchbase vector store from records, streamlining the storage and retrieval of documents. + +**Parameters:** + +- **Embedding:** Model used by Couchbase. +- **Input:** Documents or records. +- **Couchbase Cluster Connection String:** Cluster Connection string. +- **Couchbase Cluster Username:** Cluster Username. +- **Couchbase Cluster Password:** Cluster Password. +- **Bucket Name:** Bucket identifier in Couchbase. +- **Scope Name:** Scope identifier in Couchbase. +- **Collection Name:** Collection identifier in Couchbase. +- **Index Name:** Index identifier. + +For detailed documentation and integration guides, please refer to the [Couchbase Component Documentation](https://python.langchain.com/docs/integrations/vectorstores/couchbase). + +--- + +### Couchbase Search + +`CouchbaseSearch` leverages the Couchbase component to search for documents based on similarity metric. + +**Parameters:** + +- **Input:** Search query. +- **Embedding:** Model used in the Vector Store. +- **Couchbase Cluster Connection String:** Cluster Connection string. +- **Couchbase Cluster Username:** Cluster Username. +- **Couchbase Cluster Password:** Cluster Password. +- **Bucket Name:** Bucket identifier. +- **Scope Name:** Scope identifier. +- **Collection Name:** Collection identifier in Couchbase. +- **Index Name:** Index identifier. + +--- + ### FAISS The `FAISS` component manages document ingestion into a FAISS Vector Store, optimizing document indexing and retrieval. @@ -278,7 +317,8 @@ For more details, see the [PGVector Component Documentation](https://python.lang For detailed documentation, refer to the [Redis Documentation](https://python.langchain.com/docs/integrations/vectorstores/redis). - Ensure the Redis server URL and index name are configured correctly. Provide a schema if no documents are available. + Ensure the Redis server URL and index name are configured correctly. Provide a + schema if no documents are available. --- @@ -389,7 +429,8 @@ For more information, consult the [Vectara Component Documentation](https://pyth For more details, see the [Weaviate Component Documentation](https://python.langchain.com/docs/integrations/vectorstores/weaviate). - Ensure Weaviate instance is running and accessible. Verify API key, index name, text key, and attributes are set correctly. + Ensure Weaviate instance is running and accessible. Verify API key, index + name, text key, and attributes are set correctly. --- diff --git a/poetry.lock b/poetry.lock index 70b64f432..64cddfb31 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1259,6 +1259,40 @@ files = [ test = ["PyYAML", "mock", "pytest"] yaml = ["PyYAML"] +[[package]] +name = "couchbase" +version = "4.2.1" +description = "Python Client for Couchbase" +optional = false +python-versions = ">=3.7" +files = [ + {file = "couchbase-4.2.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:7ad4c4462879f456a9067ac1788e62d852509439bac3538b9bc459a754666481"}, + {file = "couchbase-4.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:06d91891c599ba0f5052e594ac025a2ca6ab7885e528b854ac9c125df7c74146"}, + {file = "couchbase-4.2.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0191d4a631ead533551cb9a214704ad5f3dfff2029e21a23b57725a0b5666b25"}, + {file = "couchbase-4.2.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b206790d6834a18c5e457f9a70f44774f476f3acccf9f22e8c1b5283a5bd03fa"}, + {file = "couchbase-4.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c5ca571b9ce017ecbd447de12cd46e213f93e0664bec6fca0a06e1768db1a4f8"}, + {file = "couchbase-4.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:675c615cfd4b04e73e94cf03c786da5105d94527f5c3a087813dba477a1379e9"}, + {file = "couchbase-4.2.1-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:4cd09eedf162dc28386d9c6490e832c25068406c0f5d70a0417c0b1445394651"}, + {file = "couchbase-4.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfebb11551c6d947ce6297ab02b5006b1ac8739dda3e10d41896db0dc8672915"}, + {file = "couchbase-4.2.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:39e742ccfe90a0e59e6e1b0e12f0fe224a736c0207b218ef48048052f926e1c6"}, + {file = "couchbase-4.2.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:f9ba24efddf47f30603275f5433434d8759a55233c78b3e4bc613c502ac429e9"}, + {file = "couchbase-4.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:adfca3929f07fb4385dc52f08d3a60634012f364b176f95ab023cdd1bb7fe9c0"}, + {file = "couchbase-4.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:e1c68b28c6f0475961afb9fe626ad2bac8a5643b53f719675386f060db4b6e19"}, + {file = "couchbase-4.2.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:137512462426cd495954c1815d78115d109308a4d9f8843b638285104388a359"}, + {file = "couchbase-4.2.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5987e5edcce7696e5f75b35be91f44fa69fb5eb95dba0957ad66f789affcdb36"}, + {file = "couchbase-4.2.1-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:080cb0fc333bd4a641ede4ee14ff0c7dbe95067fbb280826ea546681e0b9f9e3"}, + {file = "couchbase-4.2.1-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e317c2628a4a917083e8e7ce8e2662432b6a12ebac65fc00de6da2b37ab5975c"}, + {file = "couchbase-4.2.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:de7f8699ae344e2e96706ee0eac67e96bfdd3412fb18dcfb81d8ba5837dd3dfb"}, + {file = "couchbase-4.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:82b9deb8b1fe8e8d7dde9c232ac5f4c11ff0f067930837af0e7769706e6a9453"}, + {file = "couchbase-4.2.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:44502d069ea17a8d692b7c88d84bc0df2cf4e944cde337c8eb3175bc0b835bb9"}, + {file = "couchbase-4.2.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c0f131b816a7d91b755232872ba10f6d6ca5a715e595ee9534478bc97a518ae8"}, + {file = "couchbase-4.2.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e9b9deb312bbe5f9a8e63828f9de877714c4b09b7d88f7dc87b60e5ffb2a13e6"}, + {file = "couchbase-4.2.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:71e8da251850d795975c3569c01d35ba1a556825dc7d9549ff9918d148255804"}, + {file = "couchbase-4.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d04492144ce520c612a2f8f265278c9f0cdf62fdd6f703e7a3210a7476b228f6"}, + {file = "couchbase-4.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:3f91b7699ea7b8253cf34c9fb6e191de9b2edfd7aa4d6f97b29c10b9a1670444"}, + {file = "couchbase-4.2.1.tar.gz", hash = "sha256:dc1c60d3f2fc179db8225aac4cc30d601d73cf2535aaf023d607e86be2d7dd78"}, +] + [[package]] name = "coverage" version = "7.5.1" @@ -10224,5 +10258,5 @@ local = ["ctransformers", "llama-cpp-python", "sentence-transformers"] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "9e4b7f3e920342839dd51795994bdd6b993b6d0313fc715c900c4e0409acceef" +content-hash = "c68a14e273363466c1cea2bacec1798a6894d2bb18cf79ba443dc65c9344c57d" diff --git a/pyproject.toml b/pyproject.toml index b64cfd51f..cc7198812 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,7 @@ langchain-google-vertexai = "^1.0.3" langchain-groq = "^0.1.3" langchain-pinecone = "^0.1.0" langchain-mistralai = "^0.1.6" +couchbase = "^4.2.1" [tool.poetry.group.dev.dependencies] diff --git a/src/backend/base/langflow/components/vectorsearch/CouchbaseSearch.py b/src/backend/base/langflow/components/vectorsearch/CouchbaseSearch.py new file mode 100644 index 000000000..0c8a815a4 --- /dev/null +++ b/src/backend/base/langflow/components/vectorsearch/CouchbaseSearch.py @@ -0,0 +1,73 @@ +from typing import List, Optional + +from langflow.components.vectorstores.base.model import LCVectorStoreComponent +from langflow.components.vectorstores.Couchbase import CouchbaseComponent +from langflow.field_typing import Embeddings, NestedDict, Text +from langflow.schema import Record + + +class CouchbaseSearchComponent(LCVectorStoreComponent): + display_name = "Couchbase Search" + description = "Search a Couchbase Vector Store for similar documents." + documentation = "https://python.langchain.com/docs/integrations/vectorstores/couchbase" + icon = "Couchbase" + field_order = [ + "couchbase_connection_string", + "couchbase_username", + "couchbase_password", + "bucket_name", + "scope_name", + "collection_name", + "index_name", + ] + + def build_config(self): + return { + "input_value": {"display_name": "Input"}, + "embedding": {"display_name": "Embedding"}, + "couchbase_connection_string": {"display_name": "Couchbase Cluster connection string","required": True}, + "couchbase_username": {"display_name": "Couchbase username","required": True}, + "couchbase_password": { + "display_name": "Couchbase password", + "password": True, + "required": True + }, + "bucket_name": {"display_name": "Bucket Name","required": True}, + "scope_name": {"display_name": "Scope Name","required": True}, + "collection_name": {"display_name": "Collection Name","required": True}, + "index_name": {"display_name": "Index Name","required": True}, + "number_of_results": { + "display_name": "Number of Results", + "info": "Number of results to return.", + "advanced": True, + }, + } + + def build( # type: ignore[override] + self, + input_value: Text, + embedding: Embeddings, + number_of_results: int = 4, + bucket_name: str = "", + scope_name: str = "", + collection_name: str = "", + index_name: str = "", + couchbase_connection_string: str = "", + couchbase_username: str = "", + couchbase_password: str = "", + ) -> List[Record]: + vector_store = CouchbaseComponent().build( + couchbase_connection_string=couchbase_connection_string, + couchbase_username=couchbase_username, + couchbase_password=couchbase_password, + bucket_name=bucket_name, + scope_name=scope_name, + collection_name=collection_name, + embedding=embedding, + index_name=index_name, + ) + if not vector_store: + raise ValueError("Failed to create Couchbase Vector Store") + return self.search_with_vector_store( + vector_store=vector_store, input_value=input_value, search_type="similarity", k=number_of_results + ) diff --git a/src/backend/base/langflow/components/vectorsearch/__init__.py b/src/backend/base/langflow/components/vectorsearch/__init__.py index 28ea85fce..4cdf5b83c 100644 --- a/src/backend/base/langflow/components/vectorsearch/__init__.py +++ b/src/backend/base/langflow/components/vectorsearch/__init__.py @@ -9,10 +9,12 @@ from .SupabaseVectorStoreSearch import SupabaseSearchComponent from .VectaraSearch import VectaraSearchComponent from .WeaviateSearch import WeaviateSearchVectorStore from .pgvectorSearch import PGVectorSearchComponent +from .Couchbase import CouchbaseSearchComponent # type: ignore __all__ = [ "AstraDBSearchComponent", "ChromaSearchComponent", + "CouchbaseSearchComponent", "FAISSSearchComponent", "MongoDBAtlasSearchComponent", "PineconeSearchComponent", diff --git a/src/backend/base/langflow/components/vectorstores/Couchbase.py b/src/backend/base/langflow/components/vectorstores/Couchbase.py new file mode 100644 index 000000000..1816e85fb --- /dev/null +++ b/src/backend/base/langflow/components/vectorstores/Couchbase.py @@ -0,0 +1,95 @@ +from typing import List, Optional, Union + +from langchain.schema import BaseRetriever + +from langchain_community.vectorstores import CouchbaseVectorStore + +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 + + +class CouchbaseComponent(CustomComponent): + display_name = "Couchbase" + description = "Construct a `Couchbase Vector Search` vector store from raw documents." + documentation = "https://python.langchain.com/docs/integrations/vectorstores/couchbase" + icon = "Couchbase" + field_order = [ + "couchbase_connection_string", + "couchbase_username", + "couchbase_password", + "bucket_name", + "scope_name", + "collection_name", + "index_name", + ] + + def build_config(self): + return { + "inputs": {"display_name": "Input", "input_types": ["Document", "Record"]}, + "embedding": {"display_name": "Embedding"}, + "couchbase_connection_string": {"display_name": "Couchbase Cluster connection string","required": True}, + "couchbase_username": {"display_name": "Couchbase username","required": True}, + "couchbase_password": { + "display_name": "Couchbase password", + "password": True, + "required": True + }, + "bucket_name": {"display_name": "Bucket Name","required": True}, + "scope_name": {"display_name": "Scope Name","required": True}, + "collection_name": {"display_name": "Collection Name","required": True}, + "index_name": {"display_name": "Index Name","required": True}, + } + + def build( + self, + embedding: Embeddings, + inputs: Optional[List[Record]] = None, + bucket_name: str = "", + scope_name: str = "", + collection_name: str = "", + index_name: str = "", + couchbase_connection_string: str = "", + couchbase_username: str = "", + couchbase_password: str = "", + ) -> Union[VectorStore, BaseRetriever]: + try: + auth = PasswordAuthenticator(couchbase_username, couchbase_password) + options = ClusterOptions(auth) + cluster = Cluster(couchbase_connection_string, options) + + cluster.wait_until_ready(timedelta(seconds=5)) + except Exception as e: + raise ValueError(f"Failed to connect to Couchbase: {e}") + documents = [] + for _input in inputs or []: + if isinstance(_input, Record): + documents.append(_input.to_lc_document()) + else: + documents.append(_input) + if documents: + vector_store = CouchbaseVectorStore.from_documents( + documents=documents, + cluster=cluster, + bucket_name=bucket_name, + scope_name=scope_name, + collection_name=collection_name, + embedding=embedding, + index_name=index_name, + ) + else: + vector_store = CouchbaseVectorStore( + cluster=cluster, + bucket_name=bucket_name, + scope_name=scope_name, + collection_name=collection_name, + embedding=embedding, + index_name=index_name, + ) + return vector_store diff --git a/src/backend/base/langflow/components/vectorstores/__init__.py b/src/backend/base/langflow/components/vectorstores/__init__.py index 48e1bf9c7..d38b0a735 100644 --- a/src/backend/base/langflow/components/vectorstores/__init__.py +++ b/src/backend/base/langflow/components/vectorstores/__init__.py @@ -9,10 +9,12 @@ from .SupabaseVectorStore import SupabaseComponent from .Vectara import VectaraComponent from .Weaviate import WeaviateVectorStoreComponent from .pgvector import PGVectorComponent +from .Couchbase import CouchbaseComponent __all__ = [ "AstraDBVectorStoreComponent", "ChromaComponent", + "CouchbaseComponent", "FAISSComponent", "MongoDBAtlasComponent", "PineconeComponent", diff --git a/src/frontend/src/icons/Couchbase/Couchbase.jsx b/src/frontend/src/icons/Couchbase/Couchbase.jsx new file mode 100644 index 000000000..9259aae60 --- /dev/null +++ b/src/frontend/src/icons/Couchbase/Couchbase.jsx @@ -0,0 +1,17 @@ +const SvgCouchbaseIcon = (props) => ( + + + +); + +export default SvgCouchbaseIcon; diff --git a/src/frontend/src/icons/Couchbase/couchbase.svg b/src/frontend/src/icons/Couchbase/couchbase.svg new file mode 100644 index 000000000..6c86a8a9c --- /dev/null +++ b/src/frontend/src/icons/Couchbase/couchbase.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/frontend/src/icons/Couchbase/index.tsx b/src/frontend/src/icons/Couchbase/index.tsx new file mode 100644 index 000000000..85149c204 --- /dev/null +++ b/src/frontend/src/icons/Couchbase/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgCouchbaseIcon from "./Couchbase"; + +export const CouchbaseIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/utils/styleUtils.ts b/src/frontend/src/utils/styleUtils.ts index 1bedfa64d..c73ec5d23 100644 --- a/src/frontend/src/utils/styleUtils.ts +++ b/src/frontend/src/utils/styleUtils.ts @@ -153,6 +153,7 @@ import { AzureIcon } from "../icons/Azure"; import { BingIcon } from "../icons/Bing"; import { BotMessageSquareIcon } from "../icons/BotMessageSquare"; import { ChromaIcon } from "../icons/ChromaIcon"; +import { CouchbaseIcon } from "../icons/Couchbase"; import { CohereIcon } from "../icons/Cohere"; import { ElasticsearchIcon } from "../icons/ElasticsearchStore"; import { EvernoteIcon } from "../icons/Evernote"; @@ -324,6 +325,7 @@ export const nodeIconsLucide: iconsType = { Vectara: VectaraIcon, ArrowUpToLine: ArrowUpToLine, Chroma: ChromaIcon, + Couchbase: CouchbaseIcon, AirbyteJSONLoader: AirbyteIcon, AmazonBedrockEmbeddings: AWSIcon, Amazon: AWSIcon,