diff --git a/src/backend/base/langflow/base/vectorstores/model.py b/src/backend/base/langflow/base/vectorstores/model.py index ced43f88e..3603e553a 100644 --- a/src/backend/base/langflow/base/vectorstores/model.py +++ b/src/backend/base/langflow/base/vectorstores/model.py @@ -1,4 +1,4 @@ -from abc import ABC, ABCMeta, abstractmethod +from abc import abstractmethod from functools import wraps from typing import cast @@ -15,6 +15,11 @@ from langflow.schema import Data def check_cached_vector_store(f): """ Decorator to check for cached vector stores, and returns them if they exist. + + Note: caching only occurs during the execution of a component - they do not persist + across separate invocations of the component. This method exists so that components with + multiple output methods share the same vector store during the same invocation of the + component. """ @wraps(f) @@ -30,30 +35,22 @@ def check_cached_vector_store(f): return check_cached -class EnforceCacheDecoratorMeta(ABCMeta): - """ - Enforces that abstract methods marked with @check_cached_vector_store are implemented with the decorator. - """ - - def __init__(cls, name, bases, dct): - for name, value in dct.items(): - if hasattr(value, "__isabstractmethod__"): - cls._check_method_decorator(name, cls) - super().__init__(name, bases, dct) - - @staticmethod - def _check_method_decorator(name, cls): - method = getattr(cls, name) - - # Check if the method has been marked as decorated by `check_cached_vector_store` - if not getattr(method, "_is_cached_vector_store_checked", False): - raise TypeError(f"Concrete implementation of '{name}' must use '@check_cached_vector_store' decorator.") - - -class LCVectorStoreComponent(Component, ABC, metaclass=EnforceCacheDecoratorMeta): +class LCVectorStoreComponent(Component): # Used to ensure a single vector store is built for each run of the flow _cached_vector_store: VectorStore | None = None + def __init_subclass__(cls, **kwargs): + """ + Enforces the check cached decorator on all subclasses + """ + super().__init_subclass__(**kwargs) + if hasattr(cls, "build_vector_store"): + method = cls.build_vector_store + if not hasattr(method, "_is_cached_vector_store_checked"): + raise TypeError( + f"The method 'build_vector_store' in class {cls.__name__} must be decorated with @check_cached_vector_store" + ) + trace_type = "retriever" outputs = [ Output( diff --git a/src/backend/base/langflow/components/retrievers/CohereRerank.py b/src/backend/base/langflow/components/retrievers/CohereRerank.py index 5a50ac445..059229130 100644 --- a/src/backend/base/langflow/components/retrievers/CohereRerank.py +++ b/src/backend/base/langflow/components/retrievers/CohereRerank.py @@ -3,7 +3,7 @@ from typing import cast from langchain.retrievers import ContextualCompressionRetriever from langchain_cohere import CohereRerank -from langflow.base.vectorstores.model import LCVectorStoreComponent +from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store from langflow.field_typing import Retriever, VectorStore from langflow.io import ( DropdownInput, @@ -80,5 +80,6 @@ class CohereRerankComponent(LCVectorStoreComponent): self.status = data return data + @check_cached_vector_store def build_vector_store(self) -> VectorStore: raise NotImplementedError("Cohere Rerank does not support vector stores.") diff --git a/src/backend/base/langflow/components/retrievers/NvidiaRerank.py b/src/backend/base/langflow/components/retrievers/NvidiaRerank.py index c8befbc9a..04cd964d6 100644 --- a/src/backend/base/langflow/components/retrievers/NvidiaRerank.py +++ b/src/backend/base/langflow/components/retrievers/NvidiaRerank.py @@ -2,7 +2,7 @@ from typing import Any, cast from langchain.retrievers import ContextualCompressionRetriever -from langflow.base.vectorstores.model import LCVectorStoreComponent +from langflow.base.vectorstores.model import LCVectorStoreComponent, check_cached_vector_store from langflow.field_typing import Retriever, VectorStore from langflow.io import DropdownInput, HandleInput, MultilineInput, SecretStrInput, StrInput from langflow.schema import Data @@ -77,5 +77,6 @@ class NvidiaRerankComponent(LCVectorStoreComponent): self.status = data return data + @check_cached_vector_store def build_vector_store(self) -> VectorStore: raise NotImplementedError("NVIDIA Rerank does not support vector stores.") diff --git a/src/frontend/.dspy_cache/cache.db b/src/frontend/.dspy_cache/cache.db new file mode 100644 index 000000000..76b1b2425 Binary files /dev/null and b/src/frontend/.dspy_cache/cache.db differ