diff --git a/src/backend/base/langflow/base/vectorstores/model.py b/src/backend/base/langflow/base/vectorstores/model.py index f5ac1c10a..e68f826a9 100644 --- a/src/backend/base/langflow/base/vectorstores/model.py +++ b/src/backend/base/langflow/base/vectorstores/model.py @@ -1,6 +1,6 @@ from abc import abstractmethod from functools import wraps -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING from loguru import logger @@ -64,11 +64,6 @@ class LCVectorStoreComponent(Component): name="search_results", method="search_documents", ), - Output( - display_name="Vector Store", - name="vector_store", - method="cast_vector_store", - ), ] def _validate_outputs(self) -> None: @@ -120,9 +115,6 @@ class LCVectorStoreComponent(Component): self.status = data return data - def cast_vector_store(self) -> VectorStore: - return cast(VectorStore, self.build_vector_store()) - def build_base_retriever(self) -> Retriever: # type: ignore[type-var] """Builds the BaseRetriever object.""" if self._cached_vector_store is not None: diff --git a/src/backend/base/langflow/components/Notion/__init__.py b/src/backend/base/langflow/components/Notion/__init__.py index e69de29bb..bcbab1feb 100644 --- a/src/backend/base/langflow/components/Notion/__init__.py +++ b/src/backend/base/langflow/components/Notion/__init__.py @@ -0,0 +1,19 @@ +from .add_content_to_page import AddContentToPage +from .create_page import NotionPageCreator +from .list_database_properties import NotionDatabaseProperties +from .list_pages import NotionListPages +from .list_users import NotionUserList +from .page_content_viewer import NotionPageContent +from .search import NotionSearch +from .update_page_property import NotionPageUpdate + +__all__ = [ + "AddContentToPage", + "NotionPageCreator", + "NotionDatabaseProperties", + "NotionListPages", + "NotionUserList", + "NotionPageContent", + "NotionSearch", + "NotionPageUpdate", +] diff --git a/src/backend/base/langflow/components/__init__.py b/src/backend/base/langflow/components/__init__.py index 22b771454..e69de29bb 100644 --- a/src/backend/base/langflow/components/__init__.py +++ b/src/backend/base/langflow/components/__init__.py @@ -1,42 +0,0 @@ -from . import ( - agents, - chains, - custom_component, - documentloaders, - embeddings, - helpers, - inputs, - link_extractors, - memories, - models, - outputs, - prompts, - prototypes, - retrievers, - textsplitters, - toolkits, - tools, - vectorstores, -) - -__all__ = [ - "agents", - "chains", - "documentloaders", - "embeddings", - "helpers", - "inputs", - "link_extractors", - "custom_component", - "memories", - "models", - "output_parsers", - "outputs", - "prompts", - "prototypes", - "retrievers", - "textsplitters", - "toolkits", - "tools", - "vectorstores", -] diff --git a/src/backend/base/langflow/components/agents/__init__.py b/src/backend/base/langflow/components/agents/__init__.py index 245c38a97..a765520ff 100644 --- a/src/backend/base/langflow/components/agents/__init__.py +++ b/src/backend/base/langflow/components/agents/__init__.py @@ -1,29 +1,3 @@ -from .crewai import CrewAIAgentComponent -from .csv import CSVAgentComponent -from .hierarchical_crew import HierarchicalCrewComponent -from .json import JsonAgentComponent -from .openai_tools import OpenAIToolsAgentComponent -from .openapi import OpenAPIAgentComponent -from .sequential_crew import SequentialCrewComponent -from .sequential_task import SequentialTaskAgentComponent -from .sql import SQLAgentComponent -from .tool_calling import ToolCallingAgentComponent -from .vector_store import VectorStoreAgentComponent -from .vector_store_router import VectorStoreRouterAgentComponent -from .xml import XMLAgentComponent +from .agent import AgentComponent -__all__ = [ - "CSVAgentComponent", - "CrewAIAgentComponent", - "HierarchicalCrewComponent", - "JsonAgentComponent", - "OpenAIToolsAgentComponent", - "OpenAPIAgentComponent", - "SQLAgentComponent", - "SequentialCrewComponent", - "SequentialTaskAgentComponent", - "ToolCallingAgentComponent", - "VectorStoreAgentComponent", - "VectorStoreRouterAgentComponent", - "XMLAgentComponent", -] +__all__ = ["AgentComponent"] diff --git a/src/backend/base/langflow/components/agents/agent.py b/src/backend/base/langflow/components/agents/agent.py index 959b980a9..c7f9500f7 100644 --- a/src/backend/base/langflow/components/agents/agent.py +++ b/src/backend/base/langflow/components/agents/agent.py @@ -2,9 +2,9 @@ from langchain_core.tools import StructuredTool from langflow.base.agents.agent import LCToolsAgentComponent from langflow.base.models.model_input_constants import ALL_PROVIDER_FIELDS, MODEL_PROVIDERS_DICT -from langflow.components.agents.tool_calling import ToolCallingAgentComponent from langflow.components.helpers import CurrentDateComponent -from langflow.components.helpers.memory import MemoryComponent +from langflow.components.langchain_utilities.tool_calling import ToolCallingAgentComponent +from langflow.components.memories.memory import MemoryComponent from langflow.io import BoolInput, DropdownInput, MultilineInput, Output from langflow.schema.dotdict import dotdict from langflow.schema.message import Message diff --git a/src/backend/base/langflow/components/agents/vector_store.py b/src/backend/base/langflow/components/agents/vector_store.py deleted file mode 100644 index 8d161fb51..000000000 --- a/src/backend/base/langflow/components/agents/vector_store.py +++ /dev/null @@ -1,32 +0,0 @@ -from langchain.agents import AgentExecutor, create_vectorstore_agent -from langchain.agents.agent_toolkits.vectorstore.toolkit import VectorStoreToolkit - -from langflow.base.agents.agent import LCAgentComponent -from langflow.inputs import HandleInput - - -class VectorStoreAgentComponent(LCAgentComponent): - display_name = "VectorStoreAgent" - description = "Construct an agent from a Vector Store." - name = "VectorStoreAgent" - legacy: bool = True - - inputs = [ - *LCAgentComponent._base_inputs, - HandleInput( - name="llm", - display_name="Language Model", - input_types=["LanguageModel"], - required=True, - ), - HandleInput( - name="vectorstore", - display_name="Vector Store", - input_types=["VectorStoreInfo"], - required=True, - ), - ] - - def build_agent(self) -> AgentExecutor: - toolkit = VectorStoreToolkit(vectorstore_info=self.vectorstore, llm=self.llm) - return create_vectorstore_agent(llm=self.llm, toolkit=toolkit, **self.get_agent_kwargs()) diff --git a/src/backend/base/langflow/components/assemblyai/__init__.py b/src/backend/base/langflow/components/assemblyai/__init__.py index e69de29bb..f192f02dc 100644 --- a/src/backend/base/langflow/components/assemblyai/__init__.py +++ b/src/backend/base/langflow/components/assemblyai/__init__.py @@ -0,0 +1,13 @@ +from .assemblyai_get_subtitles import AssemblyAIGetSubtitles +from .assemblyai_lemur import AssemblyAILeMUR +from .assemblyai_list_transcripts import AssemblyAIListTranscripts +from .assemblyai_poll_transcript import AssemblyAITranscriptionJobPoller +from .assemblyai_start_transcript import AssemblyAITranscriptionJobCreator + +__all__ = [ + "AssemblyAIGetSubtitles", + "AssemblyAILeMUR", + "AssemblyAIListTranscripts", + "AssemblyAITranscriptionJobPoller", + "AssemblyAITranscriptionJobCreator", +] diff --git a/src/backend/base/langflow/components/astra_assistants/astra_assistant_manager.py b/src/backend/base/langflow/components/astra_assistants/astra_assistant_manager.py index 2c0520b2f..989d0162e 100644 --- a/src/backend/base/langflow/components/astra_assistants/astra_assistant_manager.py +++ b/src/backend/base/langflow/components/astra_assistants/astra_assistant_manager.py @@ -18,7 +18,7 @@ from langflow.template import Output class AstraAssistantManager(ComponentWithCache): display_name = "Astra Assistant Manager" description = "Manages Assistant Interactions" - icon = "bot" + icon = "AstraDB" inputs = [ StrInput( diff --git a/src/backend/base/langflow/components/astra_assistants/create_assistant.py b/src/backend/base/langflow/components/astra_assistants/create_assistant.py index b2d354efd..1798892f5 100644 --- a/src/backend/base/langflow/components/astra_assistants/create_assistant.py +++ b/src/backend/base/langflow/components/astra_assistants/create_assistant.py @@ -8,7 +8,7 @@ from langflow.template import Output class AssistantsCreateAssistant(ComponentWithCache): - icon = "bot" + icon = "AstraDB" display_name = "Create Assistant" description = "Creates an Assistant and returns it's id" diff --git a/src/backend/base/langflow/components/astra_assistants/create_thread.py b/src/backend/base/langflow/components/astra_assistants/create_thread.py index d7848bd2c..c41bee0fe 100644 --- a/src/backend/base/langflow/components/astra_assistants/create_thread.py +++ b/src/backend/base/langflow/components/astra_assistants/create_thread.py @@ -8,7 +8,7 @@ from langflow.template import Output class AssistantsCreateThread(ComponentWithCache): display_name = "Create Assistant Thread" description = "Creates a thread and returns the thread id" - + icon = "AstraDB" inputs = [ MultilineInput( name="env_set", diff --git a/src/backend/base/langflow/components/astra_assistants/dotenv.py b/src/backend/base/langflow/components/astra_assistants/dotenv.py index e57f98c4b..83ba991ec 100644 --- a/src/backend/base/langflow/components/astra_assistants/dotenv.py +++ b/src/backend/base/langflow/components/astra_assistants/dotenv.py @@ -11,7 +11,7 @@ from langflow.template import Output class Dotenv(Component): display_name = "Dotenv" description = "Load .env file into env vars" - + icon = "AstraDB" inputs = [ MultilineSecretInput( name="dotenv_file_content", diff --git a/src/backend/base/langflow/components/astra_assistants/get_assistant.py b/src/backend/base/langflow/components/astra_assistants/get_assistant.py index 61810ad90..8d6f05ed5 100644 --- a/src/backend/base/langflow/components/astra_assistants/get_assistant.py +++ b/src/backend/base/langflow/components/astra_assistants/get_assistant.py @@ -8,7 +8,7 @@ from langflow.template import Output class AssistantsGetAssistantName(ComponentWithCache): display_name = "Get Assistant name" description = "Assistant by id" - + icon = "AstraDB" inputs = [ StrInput( name="assistant_id", diff --git a/src/backend/base/langflow/components/astra_assistants/getenvvar.py b/src/backend/base/langflow/components/astra_assistants/getenvvar.py index 849302e21..0076cd651 100644 --- a/src/backend/base/langflow/components/astra_assistants/getenvvar.py +++ b/src/backend/base/langflow/components/astra_assistants/getenvvar.py @@ -9,7 +9,7 @@ from langflow.template import Output class GetEnvVar(Component): display_name = "Get env var" description = "Get env var" - icon = "code" + icon = "AstraDB" inputs = [ StrInput( diff --git a/src/backend/base/langflow/components/astra_assistants/list_assistants.py b/src/backend/base/langflow/components/astra_assistants/list_assistants.py index ec6fd058d..40db4db80 100644 --- a/src/backend/base/langflow/components/astra_assistants/list_assistants.py +++ b/src/backend/base/langflow/components/astra_assistants/list_assistants.py @@ -7,7 +7,7 @@ from langflow.template.field.base import Output class AssistantsListAssistants(ComponentWithCache): display_name = "List Assistants" description = "Returns a list of assistant id's" - + icon = "AstraDB" outputs = [ Output(display_name="Assistants", name="assistants", method="process_inputs"), ] diff --git a/src/backend/base/langflow/components/astra_assistants/run.py b/src/backend/base/langflow/components/astra_assistants/run.py index 9eaca3255..e065563cc 100644 --- a/src/backend/base/langflow/components/astra_assistants/run.py +++ b/src/backend/base/langflow/components/astra_assistants/run.py @@ -13,6 +13,7 @@ from langflow.template import Output class AssistantsRun(ComponentWithCache): display_name = "Run Assistant" description = "Executes an Assistant Run against a thread" + icon = "AstraDB" def __init__(self, **kwargs) -> None: super().__init__(**kwargs) diff --git a/src/backend/base/langflow/components/chains/__init__.py b/src/backend/base/langflow/components/chains/__init__.py index 550a979fd..e69de29bb 100644 --- a/src/backend/base/langflow/components/chains/__init__.py +++ b/src/backend/base/langflow/components/chains/__init__.py @@ -1,13 +0,0 @@ -from .conversation import ConversationChainComponent -from .llm_checker import LLMCheckerChainComponent -from .llm_math import LLMMathChainComponent -from .retrieval_qa import RetrievalQAComponent -from .sql_generator import SQLGeneratorComponent - -__all__ = [ - "ConversationChainComponent", - "LLMCheckerChainComponent", - "LLMMathChainComponent", - "RetrievalQAComponent", - "SQLGeneratorComponent", -] diff --git a/src/backend/base/langflow/components/cohere/__init__.py b/src/backend/base/langflow/components/cohere/__init__.py new file mode 100644 index 000000000..91945ee27 --- /dev/null +++ b/src/backend/base/langflow/components/cohere/__init__.py @@ -0,0 +1,3 @@ +from .cohere_rerank import CohereRerankComponent + +__all__ = ["CohereRerankComponent"] diff --git a/src/backend/base/langflow/components/retrievers/cohere_rerank.py b/src/backend/base/langflow/components/cohere/cohere_rerank.py similarity index 100% rename from src/backend/base/langflow/components/retrievers/cohere_rerank.py rename to src/backend/base/langflow/components/cohere/cohere_rerank.py diff --git a/src/backend/base/langflow/components/composio/__init__.py b/src/backend/base/langflow/components/composio/__init__.py new file mode 100644 index 000000000..24e438134 --- /dev/null +++ b/src/backend/base/langflow/components/composio/__init__.py @@ -0,0 +1,3 @@ +from .composio_api import ComposioAPIComponent + +__all__ = ["ComposioAPIComponent"] diff --git a/src/backend/base/langflow/components/toolkits/composio_api.py b/src/backend/base/langflow/components/composio/composio_api.py similarity index 100% rename from src/backend/base/langflow/components/toolkits/composio_api.py rename to src/backend/base/langflow/components/composio/composio_api.py diff --git a/src/backend/base/langflow/components/confluence/__init__.py b/src/backend/base/langflow/components/confluence/__init__.py new file mode 100644 index 000000000..63ccc66ac --- /dev/null +++ b/src/backend/base/langflow/components/confluence/__init__.py @@ -0,0 +1,3 @@ +from .confluence import ConfluenceComponent + +__all__ = ["ConfluenceComponent"] diff --git a/src/backend/base/langflow/components/documentloaders/confluence.py b/src/backend/base/langflow/components/confluence/confluence.py similarity index 100% rename from src/backend/base/langflow/components/documentloaders/confluence.py rename to src/backend/base/langflow/components/confluence/confluence.py diff --git a/src/backend/base/langflow/components/crewai/__init__.py b/src/backend/base/langflow/components/crewai/__init__.py new file mode 100644 index 000000000..d601c7b1c --- /dev/null +++ b/src/backend/base/langflow/components/crewai/__init__.py @@ -0,0 +1,15 @@ +from .crewai import CrewAIAgentComponent +from .hierarchical_crew import HierarchicalCrewComponent +from .hierarchical_task import HierarchicalTaskComponent +from .sequential_crew import SequentialCrewComponent +from .sequential_task import SequentialTaskComponent +from .sequential_task_agent import SequentialTaskAgentComponent + +__all__ = [ + "CrewAIAgentComponent", + "HierarchicalCrewComponent", + "HierarchicalTaskComponent", + "SequentialCrewComponent", + "SequentialTaskComponent", + "SequentialTaskAgentComponent", +] diff --git a/src/backend/base/langflow/components/agents/crewai.py b/src/backend/base/langflow/components/crewai/crewai.py similarity index 100% rename from src/backend/base/langflow/components/agents/crewai.py rename to src/backend/base/langflow/components/crewai/crewai.py diff --git a/src/backend/base/langflow/components/agents/hierarchical_crew.py b/src/backend/base/langflow/components/crewai/hierarchical_crew.py similarity index 100% rename from src/backend/base/langflow/components/agents/hierarchical_crew.py rename to src/backend/base/langflow/components/crewai/hierarchical_crew.py diff --git a/src/backend/base/langflow/components/helpers/hierarchical_task.py b/src/backend/base/langflow/components/crewai/hierarchical_task.py similarity index 100% rename from src/backend/base/langflow/components/helpers/hierarchical_task.py rename to src/backend/base/langflow/components/crewai/hierarchical_task.py diff --git a/src/backend/base/langflow/components/agents/sequential_crew.py b/src/backend/base/langflow/components/crewai/sequential_crew.py similarity index 100% rename from src/backend/base/langflow/components/agents/sequential_crew.py rename to src/backend/base/langflow/components/crewai/sequential_crew.py diff --git a/src/backend/base/langflow/components/helpers/sequential_task.py b/src/backend/base/langflow/components/crewai/sequential_task.py similarity index 100% rename from src/backend/base/langflow/components/helpers/sequential_task.py rename to src/backend/base/langflow/components/crewai/sequential_task.py diff --git a/src/backend/base/langflow/components/agents/sequential_task.py b/src/backend/base/langflow/components/crewai/sequential_task_agent.py similarity index 100% rename from src/backend/base/langflow/components/agents/sequential_task.py rename to src/backend/base/langflow/components/crewai/sequential_task_agent.py diff --git a/src/backend/base/langflow/components/data/__init__.py b/src/backend/base/langflow/components/data/__init__.py index 023b32111..820f683b8 100644 --- a/src/backend/base/langflow/components/data/__init__.py +++ b/src/backend/base/langflow/components/data/__init__.py @@ -1,7 +1,19 @@ from .api_request import APIRequestComponent +from .csv_to_data import CSVToDataComponent from .directory import DirectoryComponent from .file import FileComponent +from .json_to_data import JSONToDataComponent +from .sql_executor import SQLExecutorComponent from .url import URLComponent from .webhook import WebhookComponent -__all__ = ["APIRequestComponent", "DirectoryComponent", "FileComponent", "URLComponent", "WebhookComponent"] +__all__ = [ + "APIRequestComponent", + "CSVToDataComponent", + "DirectoryComponent", + "FileComponent", + "SQLExecutorComponent", + "URLComponent", + "WebhookComponent", + "JSONToDataComponent", +] diff --git a/src/backend/base/langflow/components/helpers/csv_to_data.py b/src/backend/base/langflow/components/data/csv_to_data.py similarity index 100% rename from src/backend/base/langflow/components/helpers/csv_to_data.py rename to src/backend/base/langflow/components/data/csv_to_data.py diff --git a/src/backend/base/langflow/components/helpers/json_to_data.py b/src/backend/base/langflow/components/data/json_to_data.py similarity index 99% rename from src/backend/base/langflow/components/helpers/json_to_data.py rename to src/backend/base/langflow/components/data/json_to_data.py index 73e31f656..83131f0f1 100644 --- a/src/backend/base/langflow/components/helpers/json_to_data.py +++ b/src/backend/base/langflow/components/data/json_to_data.py @@ -9,7 +9,7 @@ from langflow.schema import Data class JSONToDataComponent(Component): - display_name = "JSON to Data" + display_name = "Load JSON" description = ( "Convert a JSON file, JSON from a file path, or a JSON string to a Data object or a list of Data objects" ) diff --git a/src/backend/base/langflow/components/prototypes/sql_executor.py b/src/backend/base/langflow/components/data/sql_executor.py similarity index 100% rename from src/backend/base/langflow/components/prototypes/sql_executor.py rename to src/backend/base/langflow/components/data/sql_executor.py diff --git a/src/backend/base/langflow/components/data/webhook.py b/src/backend/base/langflow/components/data/webhook.py index e02367332..b41d24ac0 100644 --- a/src/backend/base/langflow/components/data/webhook.py +++ b/src/backend/base/langflow/components/data/webhook.py @@ -6,14 +6,14 @@ from langflow.schema import Data class WebhookComponent(Component): - display_name = "Webhook Input" + display_name = "Webhook" description = "Defines a webhook input for the flow." name = "Webhook" inputs = [ MultilineInput( name="data", - display_name="Data", + display_name="JSON Payload", info="Use this field to quickly test the webhook component by providing a JSON payload.", ) ] diff --git a/src/backend/base/langflow/components/deactivated/__init__.py b/src/backend/base/langflow/components/deactivated/__init__.py index 6d127f956..9cf7ac2dc 100644 --- a/src/backend/base/langflow/components/deactivated/__init__.py +++ b/src/backend/base/langflow/components/deactivated/__init__.py @@ -6,7 +6,6 @@ from .split_text import SplitTextComponent from .sub_flow import SubFlowComponent __all__ = [ - "ConditionalRouterComponent", "ExtractKeyFromDataComponent", "FlowToolComponent", "ListFlowsComponent", diff --git a/src/backend/base/langflow/components/documentloaders/__init__.py b/src/backend/base/langflow/components/documentloaders/__init__.py index a223723ae..e69de29bb 100644 --- a/src/backend/base/langflow/components/documentloaders/__init__.py +++ b/src/backend/base/langflow/components/documentloaders/__init__.py @@ -1,5 +0,0 @@ -from .confluence import ConfluenceComponent -from .git import GitLoaderComponent -from .unstructured import UnstructuredComponent - -__all__ = ["ConfluenceComponent", "GitLoaderComponent", "UnstructuredComponent"] diff --git a/src/backend/base/langflow/components/embeddings/__init__.py b/src/backend/base/langflow/components/embeddings/__init__.py index afb0ef349..100ff9ade 100644 --- a/src/backend/base/langflow/components/embeddings/__init__.py +++ b/src/backend/base/langflow/components/embeddings/__init__.py @@ -5,8 +5,13 @@ from .azure_openai import AzureOpenAIEmbeddingsComponent from .cohere import CohereEmbeddingsComponent from .google_generative_ai import GoogleGenerativeAIEmbeddingsComponent from .huggingface_inference_api import HuggingFaceInferenceAPIEmbeddingsComponent +from .lmstudioembeddings import LMStudioEmbeddingsComponent +from .mistral import MistralAIEmbeddingsComponent +from .nvidia import NVIDIAEmbeddingsComponent from .ollama import OllamaEmbeddingsComponent from .openai import OpenAIEmbeddingsComponent +from .similarity import EmbeddingSimilarityComponent +from .text_embedder import TextEmbedderComponent from .vertexai import VertexAIEmbeddingsComponent __all__ = [ @@ -17,7 +22,12 @@ __all__ = [ "CohereEmbeddingsComponent", "GoogleGenerativeAIEmbeddingsComponent", "HuggingFaceInferenceAPIEmbeddingsComponent", + "LMStudioEmbeddingsComponent", + "MistralAIEmbeddingsComponent", + "NVIDIAEmbeddingsComponent", "OllamaEmbeddingsComponent", "OpenAIEmbeddingsComponent", + "EmbeddingSimilarityComponent", + "TextEmbedderComponent", "VertexAIEmbeddingsComponent", ] diff --git a/src/backend/base/langflow/components/firecrawl/__init__.py b/src/backend/base/langflow/components/firecrawl/__init__.py new file mode 100644 index 000000000..9c1a2cec2 --- /dev/null +++ b/src/backend/base/langflow/components/firecrawl/__init__.py @@ -0,0 +1,4 @@ +from .firecrawl_crawl_api import FirecrawlCrawlApi +from .firecrawl_scrape_api import FirecrawlScrapeApi + +__all__ = ["FirecrawlCrawlApi", "FirecrawlScrapeApi"] diff --git a/src/backend/base/langflow/components/langchain_utilities/firecrawl_crawl_api.py b/src/backend/base/langflow/components/firecrawl/firecrawl_crawl_api.py similarity index 100% rename from src/backend/base/langflow/components/langchain_utilities/firecrawl_crawl_api.py rename to src/backend/base/langflow/components/firecrawl/firecrawl_crawl_api.py diff --git a/src/backend/base/langflow/components/langchain_utilities/firecrawl_scrape_api.py b/src/backend/base/langflow/components/firecrawl/firecrawl_scrape_api.py similarity index 100% rename from src/backend/base/langflow/components/langchain_utilities/firecrawl_scrape_api.py rename to src/backend/base/langflow/components/firecrawl/firecrawl_scrape_api.py diff --git a/src/backend/base/langflow/components/git/__init__.py b/src/backend/base/langflow/components/git/__init__.py new file mode 100644 index 000000000..20de11c02 --- /dev/null +++ b/src/backend/base/langflow/components/git/__init__.py @@ -0,0 +1,3 @@ +from .git import GitLoaderComponent + +__all__ = ["GitLoaderComponent"] diff --git a/src/backend/base/langflow/components/documentloaders/git.py b/src/backend/base/langflow/components/git/git.py similarity index 100% rename from src/backend/base/langflow/components/documentloaders/git.py rename to src/backend/base/langflow/components/git/git.py diff --git a/src/backend/base/langflow/components/google/__init__.py b/src/backend/base/langflow/components/google/__init__.py new file mode 100644 index 000000000..dfbf6767d --- /dev/null +++ b/src/backend/base/langflow/components/google/__init__.py @@ -0,0 +1,5 @@ +from .gmail import GmailLoaderComponent +from .google_drive import GoogleDriveComponent +from .google_drive_search import GoogleDriveSearchComponent + +__all__ = ["GmailLoaderComponent", "GoogleDriveComponent", "GoogleDriveSearchComponent"] diff --git a/src/backend/base/langflow/components/data/gmail.py b/src/backend/base/langflow/components/google/gmail.py similarity index 100% rename from src/backend/base/langflow/components/data/gmail.py rename to src/backend/base/langflow/components/google/gmail.py diff --git a/src/backend/base/langflow/components/data/google_drive.py b/src/backend/base/langflow/components/google/google_drive.py similarity index 100% rename from src/backend/base/langflow/components/data/google_drive.py rename to src/backend/base/langflow/components/google/google_drive.py diff --git a/src/backend/base/langflow/components/data/google_drive_search.py b/src/backend/base/langflow/components/google/google_drive_search.py similarity index 100% rename from src/backend/base/langflow/components/data/google_drive_search.py rename to src/backend/base/langflow/components/google/google_drive_search.py diff --git a/src/backend/base/langflow/components/helpers/__init__.py b/src/backend/base/langflow/components/helpers/__init__.py index b78c7fdee..2b9eec070 100644 --- a/src/backend/base/langflow/components/helpers/__init__.py +++ b/src/backend/base/langflow/components/helpers/__init__.py @@ -1,45 +1,15 @@ -from .combine_text import CombineTextComponent from .create_list import CreateListComponent -from .csv_to_data import CSVToDataComponent from .current_date import CurrentDateComponent -from .data_conditional_router import DataConditionalRouterComponent -from .extract_key import ExtractDataKeyComponent -from .filter_data import FilterDataComponent -from .filter_data_values import DataFilterComponent -from .hierarchical_task import HierarchicalTaskComponent from .id_generator import IDGeneratorComponent -from .json_to_data import JSONToDataComponent -from .memory import MemoryComponent -from .merge_data import MergeDataComponent -from .message_to_data import MessageToDataComponent -from .parse_data import ParseDataComponent -from .parse_json_data import ParseJSONDataComponent -from .sequential_task import SequentialTaskComponent +from .output_parser import OutputParserComponent from .split_text import SplitTextComponent -from .store_message import StoreMessageComponent from .structured_output import StructuredOutputComponent __all__ = [ - "CSVToDataComponent", - "CombineTextComponent", "CreateListComponent", "CurrentDateComponent", - "DataConditionalRouterComponent", - "DataFilterComponent", - "ExtractDataKeyComponent", - "FilterDataComponent", - "FilterDataComponent", - "HierarchicalTaskComponent", "IDGeneratorComponent", - "IDGeneratorComponent", - "JSONToDataComponent", - "MemoryComponent", - "MergeDataComponent", - "MessageToDataComponent", - "ParseDataComponent", - "ParseJSONDataComponent", - "SequentialTaskComponent", + "OutputParserComponent", "SplitTextComponent", - "StoreMessageComponent", "StructuredOutputComponent", ] diff --git a/src/backend/base/langflow/components/helpers/create_list.py b/src/backend/base/langflow/components/helpers/create_list.py index 678500b23..a978ffe1f 100644 --- a/src/backend/base/langflow/components/helpers/create_list.py +++ b/src/backend/base/langflow/components/helpers/create_list.py @@ -9,6 +9,7 @@ class CreateListComponent(Component): description = "Creates a list of texts." icon = "list" name = "CreateList" + legacy = True inputs = [ StrInput( diff --git a/src/backend/base/langflow/components/output_parsers/output_parser.py b/src/backend/base/langflow/components/helpers/output_parser.py similarity index 100% rename from src/backend/base/langflow/components/output_parsers/output_parser.py rename to src/backend/base/langflow/components/helpers/output_parser.py diff --git a/src/backend/base/langflow/components/helpers/structured_output.py b/src/backend/base/langflow/components/helpers/structured_output.py index f87651e5f..2af859710 100644 --- a/src/backend/base/langflow/components/helpers/structured_output.py +++ b/src/backend/base/langflow/components/helpers/structured_output.py @@ -16,6 +16,8 @@ class StructuredOutputComponent(Component): "Transforms LLM responses into **structured data formats**. Ideal for extracting specific information " "or creating consistent outputs." ) + icon = "braces" + inputs = [ HandleInput( name="llm", diff --git a/src/backend/base/langflow/components/langchain_utilities/__init__.py b/src/backend/base/langflow/components/langchain_utilities/__init__.py index e69de29bb..16961327e 100644 --- a/src/backend/base/langflow/components/langchain_utilities/__init__.py +++ b/src/backend/base/langflow/components/langchain_utilities/__init__.py @@ -0,0 +1,57 @@ +from .character import CharacterTextSplitterComponent +from .conversation import ConversationChainComponent +from .csv import CSVAgentComponent +from .html_link_extractor import HtmlLinkExtractorComponent +from .json import JsonAgentComponent +from .json_document_builder import JSONDocumentBuilder +from .langchain_hub import LangChainHubPromptComponent +from .language_recursive import LanguageRecursiveTextSplitterComponent +from .language_semantic import SemanticTextSplitterComponent +from .llm_checker import LLMCheckerChainComponent +from .llm_math import LLMMathChainComponent +from .natural_language import NaturalLanguageTextSplitterComponent +from .openai_tools import OpenAIToolsAgentComponent +from .openapi import OpenAPIAgentComponent +from .recursive_character import RecursiveCharacterTextSplitterComponent +from .retrieval_qa import RetrievalQAComponent +from .runnable_executor import RunnableExecComponent +from .self_query import SelfQueryRetrieverComponent +from .spider import SpiderTool +from .sql import SQLAgentComponent +from .sql_database import SQLDatabaseComponent +from .sql_generator import SQLGeneratorComponent +from .tool_calling import ToolCallingAgentComponent +from .vector_store import VectoStoreRetrieverComponent +from .vector_store_info import VectorStoreInfoComponent +from .vector_store_router import VectorStoreRouterAgentComponent +from .xml import XMLAgentComponent + +__all__ = [ + "CharacterTextSplitterComponent", + "ConversationChainComponent", + "CSVAgentComponent", + "HtmlLinkExtractorComponent", + "JSONDocumentBuilder", + "JsonAgentComponent", + "LangChainHubPromptComponent", + "LanguageRecursiveTextSplitterComponent", + "LLMCheckerChainComponent", + "LLMMathChainComponent", + "NaturalLanguageTextSplitterComponent", + "OpenAIToolsAgentComponent", + "OpenAPIAgentComponent", + "RecursiveCharacterTextSplitterComponent", + "RetrievalQAComponent", + "RunnableExecComponent", + "SelfQueryRetrieverComponent", + "SpiderTool", + "SQLAgentComponent", + "SQLDatabaseComponent", + "SQLGeneratorComponent", + "ToolCallingAgentComponent", + "VectoStoreRetrieverComponent", + "VectorStoreInfoComponent", + "VectorStoreRouterAgentComponent", + "XMLAgentComponent", + "SemanticTextSplitterComponent", +] diff --git a/src/backend/base/langflow/components/textsplitters/character.py b/src/backend/base/langflow/components/langchain_utilities/character.py similarity index 98% rename from src/backend/base/langflow/components/textsplitters/character.py rename to src/backend/base/langflow/components/langchain_utilities/character.py index cfb1baa73..0dff4f13f 100644 --- a/src/backend/base/langflow/components/textsplitters/character.py +++ b/src/backend/base/langflow/components/langchain_utilities/character.py @@ -12,6 +12,7 @@ class CharacterTextSplitterComponent(LCTextSplitterComponent): description = "Split text by number of characters." documentation = "https://docs.langflow.org/components/text-splitters#charactertextsplitter" name = "CharacterTextSplitter" + icon = "LangChain" inputs = [ IntInput( diff --git a/src/backend/base/langflow/components/chains/conversation.py b/src/backend/base/langflow/components/langchain_utilities/conversation.py similarity index 98% rename from src/backend/base/langflow/components/chains/conversation.py rename to src/backend/base/langflow/components/langchain_utilities/conversation.py index b6d59fcd0..6e9cbaa60 100644 --- a/src/backend/base/langflow/components/chains/conversation.py +++ b/src/backend/base/langflow/components/langchain_utilities/conversation.py @@ -10,6 +10,7 @@ class ConversationChainComponent(LCChainComponent): description = "Chain to have a conversation and load context from memory." name = "ConversationChain" legacy: bool = True + icon = "LangChain" inputs = [ MultilineInput( diff --git a/src/backend/base/langflow/components/agents/csv.py b/src/backend/base/langflow/components/langchain_utilities/csv.py similarity index 99% rename from src/backend/base/langflow/components/agents/csv.py rename to src/backend/base/langflow/components/langchain_utilities/csv.py index b638a7f76..8fcb49278 100644 --- a/src/backend/base/langflow/components/agents/csv.py +++ b/src/backend/base/langflow/components/langchain_utilities/csv.py @@ -13,6 +13,7 @@ class CSVAgentComponent(LCAgentComponent): description = "Construct a CSV agent from a CSV and tools." documentation = "https://python.langchain.com/docs/modules/agents/toolkits/csv" name = "CSVAgent" + icon = "LangChain" inputs = [ *LCAgentComponent._base_inputs, diff --git a/src/backend/base/langflow/components/link_extractors/html_link_extractor.py b/src/backend/base/langflow/components/langchain_utilities/html_link_extractor.py similarity index 98% rename from src/backend/base/langflow/components/link_extractors/html_link_extractor.py rename to src/backend/base/langflow/components/langchain_utilities/html_link_extractor.py index af8e9eb64..824b04ea1 100644 --- a/src/backend/base/langflow/components/link_extractors/html_link_extractor.py +++ b/src/backend/base/langflow/components/langchain_utilities/html_link_extractor.py @@ -12,6 +12,7 @@ class HtmlLinkExtractorComponent(LCDocumentTransformerComponent): description = "Extract hyperlinks from HTML content." documentation = "https://python.langchain.com/v0.2/api_reference/community/graph_vectorstores/langchain_community.graph_vectorstores.extractors.html_link_extractor.HtmlLinkExtractor.html" name = "HtmlLinkExtractor" + icon = "LangChain" inputs = [ StrInput(name="kind", display_name="Kind of edge", value="hyperlink", required=False), diff --git a/src/backend/base/langflow/components/agents/json.py b/src/backend/base/langflow/components/langchain_utilities/json.py similarity index 100% rename from src/backend/base/langflow/components/agents/json.py rename to src/backend/base/langflow/components/langchain_utilities/json.py diff --git a/src/backend/base/langflow/components/prompts/langchain_hub.py b/src/backend/base/langflow/components/langchain_utilities/langchain_hub.py similarity index 99% rename from src/backend/base/langflow/components/prompts/langchain_hub.py rename to src/backend/base/langflow/components/langchain_utilities/langchain_hub.py index 89dc38eec..2d4ad6e4b 100644 --- a/src/backend/base/langflow/components/prompts/langchain_hub.py +++ b/src/backend/base/langflow/components/langchain_utilities/langchain_hub.py @@ -12,7 +12,7 @@ class LangChainHubPromptComponent(Component): display_name: str = "LangChain Hub" description: str = "Prompt Component that uses LangChain Hub prompts" beta = True - icon = "prompts" + icon = "LangChain" trace_type = "prompt" name = "LangChain Hub Prompt" diff --git a/src/backend/base/langflow/components/textsplitters/language_recursive.py b/src/backend/base/langflow/components/langchain_utilities/language_recursive.py similarity index 98% rename from src/backend/base/langflow/components/textsplitters/language_recursive.py rename to src/backend/base/langflow/components/langchain_utilities/language_recursive.py index dab795eb7..0a454cf43 100644 --- a/src/backend/base/langflow/components/textsplitters/language_recursive.py +++ b/src/backend/base/langflow/components/langchain_utilities/language_recursive.py @@ -11,6 +11,7 @@ class LanguageRecursiveTextSplitterComponent(LCTextSplitterComponent): description: str = "Split text into chunks of a specified length based on language." documentation: str = "https://docs.langflow.org/components/text-splitters#languagerecursivetextsplitter" name = "LanguageRecursiveTextSplitter" + icon = "LangChain" inputs = [ IntInput( diff --git a/src/backend/base/langflow/components/textsplitters/language_semantic.py b/src/backend/base/langflow/components/langchain_utilities/language_semantic.py similarity index 99% rename from src/backend/base/langflow/components/textsplitters/language_semantic.py rename to src/backend/base/langflow/components/langchain_utilities/language_semantic.py index df0ad5e34..261e6e294 100644 --- a/src/backend/base/langflow/components/textsplitters/language_semantic.py +++ b/src/backend/base/langflow/components/langchain_utilities/language_semantic.py @@ -21,6 +21,7 @@ class SemanticTextSplitterComponent(LCTextSplitterComponent): description: str = "Split text into semantically meaningful chunks using semantic similarity." documentation = "https://python.langchain.com/docs/how_to/semantic-chunker/" beta = True # this component is beta because it is imported from langchain_experimental + icon = "LangChain" inputs = [ HandleInput( diff --git a/src/backend/base/langflow/components/chains/llm_checker.py b/src/backend/base/langflow/components/langchain_utilities/llm_checker.py similarity index 98% rename from src/backend/base/langflow/components/chains/llm_checker.py rename to src/backend/base/langflow/components/langchain_utilities/llm_checker.py index 9f8294dde..b9ba6a93d 100644 --- a/src/backend/base/langflow/components/chains/llm_checker.py +++ b/src/backend/base/langflow/components/langchain_utilities/llm_checker.py @@ -11,7 +11,7 @@ class LLMCheckerChainComponent(LCChainComponent): documentation = "https://python.langchain.com/docs/modules/chains/additional/llm_checker" name = "LLMCheckerChain" legacy: bool = True - + icon = "LangChain" inputs = [ MultilineInput( name="input_value", diff --git a/src/backend/base/langflow/components/chains/llm_math.py b/src/backend/base/langflow/components/langchain_utilities/llm_math.py similarity index 98% rename from src/backend/base/langflow/components/chains/llm_math.py rename to src/backend/base/langflow/components/langchain_utilities/llm_math.py index 940d75e96..3d592e4a3 100644 --- a/src/backend/base/langflow/components/chains/llm_math.py +++ b/src/backend/base/langflow/components/langchain_utilities/llm_math.py @@ -12,7 +12,7 @@ class LLMMathChainComponent(LCChainComponent): documentation = "https://python.langchain.com/docs/modules/chains/additional/llm_math" name = "LLMMathChain" legacy: bool = True - + icon = "LangChain" inputs = [ MultilineInput( name="input_value", diff --git a/src/backend/base/langflow/components/textsplitters/natural_language.py b/src/backend/base/langflow/components/langchain_utilities/natural_language.py similarity index 98% rename from src/backend/base/langflow/components/textsplitters/natural_language.py rename to src/backend/base/langflow/components/langchain_utilities/natural_language.py index 40f2d6825..3a3b3a938 100644 --- a/src/backend/base/langflow/components/textsplitters/natural_language.py +++ b/src/backend/base/langflow/components/langchain_utilities/natural_language.py @@ -14,7 +14,7 @@ class NaturalLanguageTextSplitterComponent(LCTextSplitterComponent): "https://python.langchain.com/v0.1/docs/modules/data_connection/document_transformers/split_by_token/#nltk" ) name = "NaturalLanguageTextSplitter" - + icon = "LangChain" inputs = [ IntInput( name="chunk_size", diff --git a/src/backend/base/langflow/components/agents/openai_tools.py b/src/backend/base/langflow/components/langchain_utilities/openai_tools.py similarity index 99% rename from src/backend/base/langflow/components/agents/openai_tools.py rename to src/backend/base/langflow/components/langchain_utilities/openai_tools.py index e9b925db0..c529330c5 100644 --- a/src/backend/base/langflow/components/agents/openai_tools.py +++ b/src/backend/base/langflow/components/langchain_utilities/openai_tools.py @@ -11,7 +11,6 @@ class OpenAIToolsAgentComponent(LCToolsAgentComponent): display_name: str = "OpenAI Tools Agent" description: str = "Agent that uses tools via openai-tools." icon = "LangChain" - beta = True name = "OpenAIToolsAgent" inputs = [ diff --git a/src/backend/base/langflow/components/agents/openapi.py b/src/backend/base/langflow/components/langchain_utilities/openapi.py similarity index 98% rename from src/backend/base/langflow/components/agents/openapi.py rename to src/backend/base/langflow/components/langchain_utilities/openapi.py index 08de012fb..2b58295f3 100644 --- a/src/backend/base/langflow/components/agents/openapi.py +++ b/src/backend/base/langflow/components/langchain_utilities/openapi.py @@ -15,7 +15,7 @@ class OpenAPIAgentComponent(LCAgentComponent): display_name = "OpenAPI Agent" description = "Agent to interact with OpenAPI API." name = "OpenAPIAgent" - + icon = "LangChain" inputs = [ *LCAgentComponent._base_inputs, HandleInput(name="llm", display_name="Language Model", input_types=["LanguageModel"], required=True), diff --git a/src/backend/base/langflow/components/textsplitters/recursive_character.py b/src/backend/base/langflow/components/langchain_utilities/recursive_character.py similarity index 98% rename from src/backend/base/langflow/components/textsplitters/recursive_character.py rename to src/backend/base/langflow/components/langchain_utilities/recursive_character.py index 992552113..6dd9c6173 100644 --- a/src/backend/base/langflow/components/textsplitters/recursive_character.py +++ b/src/backend/base/langflow/components/langchain_utilities/recursive_character.py @@ -12,6 +12,7 @@ class RecursiveCharacterTextSplitterComponent(LCTextSplitterComponent): description: str = "Split text trying to keep all related text together." documentation: str = "https://docs.langflow.org/components/text-splitters#recursivecharactertextsplitter" name = "RecursiveCharacterTextSplitter" + icon = "LangChain" inputs = [ IntInput( diff --git a/src/backend/base/langflow/components/chains/retrieval_qa.py b/src/backend/base/langflow/components/langchain_utilities/retrieval_qa.py similarity index 99% rename from src/backend/base/langflow/components/chains/retrieval_qa.py rename to src/backend/base/langflow/components/langchain_utilities/retrieval_qa.py index d3d55db1f..deebd7b54 100644 --- a/src/backend/base/langflow/components/chains/retrieval_qa.py +++ b/src/backend/base/langflow/components/langchain_utilities/retrieval_qa.py @@ -10,7 +10,7 @@ class RetrievalQAComponent(LCChainComponent): description = "Chain for question-answering querying sources from a retriever." name = "RetrievalQA" legacy: bool = True - + icon = "LangChain" inputs = [ MultilineInput( name="input_value", diff --git a/src/backend/base/langflow/components/prototypes/runnable_executor.py b/src/backend/base/langflow/components/langchain_utilities/runnable_executor.py similarity index 99% rename from src/backend/base/langflow/components/prototypes/runnable_executor.py rename to src/backend/base/langflow/components/langchain_utilities/runnable_executor.py index f756ee11d..7bcd46279 100644 --- a/src/backend/base/langflow/components/prototypes/runnable_executor.py +++ b/src/backend/base/langflow/components/langchain_utilities/runnable_executor.py @@ -11,6 +11,7 @@ class RunnableExecComponent(Component): display_name = "Runnable Executor" name = "RunnableExecutor" beta: bool = True + icon = "LangChain" inputs = [ MessageTextInput(name="input_value", display_name="Input", required=True), diff --git a/src/backend/base/langflow/components/retrievers/self_query.py b/src/backend/base/langflow/components/langchain_utilities/self_query.py similarity index 100% rename from src/backend/base/langflow/components/retrievers/self_query.py rename to src/backend/base/langflow/components/langchain_utilities/self_query.py diff --git a/src/backend/base/langflow/components/agents/sql.py b/src/backend/base/langflow/components/langchain_utilities/sql.py similarity index 98% rename from src/backend/base/langflow/components/agents/sql.py rename to src/backend/base/langflow/components/langchain_utilities/sql.py index bb0f52c91..e018dec62 100644 --- a/src/backend/base/langflow/components/agents/sql.py +++ b/src/backend/base/langflow/components/langchain_utilities/sql.py @@ -11,7 +11,7 @@ class SQLAgentComponent(LCAgentComponent): display_name = "SQLAgent" description = "Construct an SQL agent from an LLM and tools." name = "SQLAgent" - + icon = "LangChain" inputs = [ *LCAgentComponent._base_inputs, HandleInput(name="llm", display_name="Language Model", input_types=["LanguageModel"], required=True), diff --git a/src/backend/base/langflow/components/chains/sql_generator.py b/src/backend/base/langflow/components/langchain_utilities/sql_generator.py similarity index 99% rename from src/backend/base/langflow/components/chains/sql_generator.py rename to src/backend/base/langflow/components/langchain_utilities/sql_generator.py index a516a8c3d..3743aeffe 100644 --- a/src/backend/base/langflow/components/chains/sql_generator.py +++ b/src/backend/base/langflow/components/langchain_utilities/sql_generator.py @@ -17,6 +17,7 @@ class SQLGeneratorComponent(LCChainComponent): description = "Generate SQL from natural language." name = "SQLGenerator" legacy: bool = True + icon = "LangChain" inputs = [ MultilineInput( diff --git a/src/backend/base/langflow/components/agents/tool_calling.py b/src/backend/base/langflow/components/langchain_utilities/tool_calling.py similarity index 99% rename from src/backend/base/langflow/components/agents/tool_calling.py rename to src/backend/base/langflow/components/langchain_utilities/tool_calling.py index 73ffae06b..92b169a9e 100644 --- a/src/backend/base/langflow/components/agents/tool_calling.py +++ b/src/backend/base/langflow/components/langchain_utilities/tool_calling.py @@ -11,7 +11,6 @@ class ToolCallingAgentComponent(LCToolsAgentComponent): display_name: str = "Tool Calling Agent" description: str = "An agent designed to utilize various tools seamlessly within workflows." icon = "LangChain" - beta = True name = "ToolCallingAgent" inputs = [ diff --git a/src/backend/base/langflow/components/retrievers/vector_store.py b/src/backend/base/langflow/components/langchain_utilities/vector_store.py similarity index 96% rename from src/backend/base/langflow/components/retrievers/vector_store.py rename to src/backend/base/langflow/components/langchain_utilities/vector_store.py index 6243725e5..dfd56deb0 100644 --- a/src/backend/base/langflow/components/retrievers/vector_store.py +++ b/src/backend/base/langflow/components/langchain_utilities/vector_store.py @@ -9,6 +9,7 @@ class VectoStoreRetrieverComponent(CustomComponent): description = "A vector store retriever" name = "VectorStoreRetriever" legacy: bool = True + icon = "LangChain" def build_config(self): return { diff --git a/src/backend/base/langflow/components/toolkits/vector_store_info.py b/src/backend/base/langflow/components/langchain_utilities/vector_store_info.py similarity index 98% rename from src/backend/base/langflow/components/toolkits/vector_store_info.py rename to src/backend/base/langflow/components/langchain_utilities/vector_store_info.py index 5961756b0..4658f05dc 100644 --- a/src/backend/base/langflow/components/toolkits/vector_store_info.py +++ b/src/backend/base/langflow/components/langchain_utilities/vector_store_info.py @@ -10,6 +10,7 @@ class VectorStoreInfoComponent(Component): description = "Information about a VectorStore" name = "VectorStoreInfo" legacy: bool = True + icon = "LangChain" inputs = [ MessageTextInput( diff --git a/src/backend/base/langflow/components/agents/vector_store_router.py b/src/backend/base/langflow/components/langchain_utilities/vector_store_router.py similarity index 100% rename from src/backend/base/langflow/components/agents/vector_store_router.py rename to src/backend/base/langflow/components/langchain_utilities/vector_store_router.py diff --git a/src/backend/base/langflow/components/agents/xml.py b/src/backend/base/langflow/components/langchain_utilities/xml.py similarity index 100% rename from src/backend/base/langflow/components/agents/xml.py rename to src/backend/base/langflow/components/langchain_utilities/xml.py diff --git a/src/backend/base/langflow/components/link_extractors/__init__.py b/src/backend/base/langflow/components/link_extractors/__init__.py index 66ceda375..e69de29bb 100644 --- a/src/backend/base/langflow/components/link_extractors/__init__.py +++ b/src/backend/base/langflow/components/link_extractors/__init__.py @@ -1,5 +0,0 @@ -from .html_link_extractor import HtmlLinkExtractorComponent - -__all__ = [ - "HtmlLinkExtractorComponent", -] diff --git a/src/backend/base/langflow/components/logic/__init__.py b/src/backend/base/langflow/components/logic/__init__.py new file mode 100644 index 000000000..039d6c52d --- /dev/null +++ b/src/backend/base/langflow/components/logic/__init__.py @@ -0,0 +1,19 @@ +from .conditional_router import ConditionalRouterComponent +from .data_conditional_router import DataConditionalRouterComponent +from .flow_tool import FlowToolComponent +from .listen import ListenComponent +from .notify import NotifyComponent +from .pass_message import PassMessageComponent +from .run_flow import RunFlowComponent +from .sub_flow import SubFlowComponent + +__all__ = [ + "DataConditionalRouterComponent", + "FlowToolComponent", + "ListenComponent", + "NotifyComponent", + "RunFlowComponent", + "SubFlowComponent", + "ConditionalRouterComponent", + "PassMessageComponent", +] diff --git a/src/backend/base/langflow/components/prototypes/conditional_router.py b/src/backend/base/langflow/components/logic/conditional_router.py similarity index 93% rename from src/backend/base/langflow/components/prototypes/conditional_router.py rename to src/backend/base/langflow/components/logic/conditional_router.py index ced08e3bd..81a5be96c 100644 --- a/src/backend/base/langflow/components/prototypes/conditional_router.py +++ b/src/backend/base/langflow/components/logic/conditional_router.py @@ -4,10 +4,11 @@ from langflow.schema.message import Message class ConditionalRouterComponent(Component): - display_name = "Conditional Router" + display_name = "If-Else" description = "Routes an input message to a corresponding output based on text comparison." - icon = "equal" + icon = "split" name = "ConditionalRouter" + legacy = True def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @@ -16,7 +17,7 @@ class ConditionalRouterComponent(Component): inputs = [ MessageTextInput( name="input_text", - display_name="Input Text", + display_name="Text Input", info="The primary text input for the operation.", ), MessageTextInput( @@ -30,7 +31,6 @@ class ConditionalRouterComponent(Component): options=["equals", "not equals", "contains", "starts with", "ends with"], info="The operator to apply for comparing the texts.", value="equals", - advanced=True, ), BoolInput( name="case_sensitive", @@ -43,6 +43,7 @@ class ConditionalRouterComponent(Component): name="message", display_name="Message", info="The message to pass through either route.", + advanced=True, ), IntInput( name="max_iterations", @@ -61,8 +62,8 @@ class ConditionalRouterComponent(Component): ] outputs = [ - Output(display_name="True Route", name="true_result", method="true_response"), - Output(display_name="False Route", name="false_result", method="false_response"), + Output(display_name="True", name="true_result", method="true_response"), + Output(display_name="False", name="false_result", method="false_response"), ] def _pre_run_setup(self): diff --git a/src/backend/base/langflow/components/helpers/data_conditional_router.py b/src/backend/base/langflow/components/logic/data_conditional_router.py similarity index 97% rename from src/backend/base/langflow/components/helpers/data_conditional_router.py rename to src/backend/base/langflow/components/logic/data_conditional_router.py index 213718589..3419554d8 100644 --- a/src/backend/base/langflow/components/helpers/data_conditional_router.py +++ b/src/backend/base/langflow/components/logic/data_conditional_router.py @@ -6,11 +6,12 @@ from langflow.schema import Data, dotdict class DataConditionalRouterComponent(Component): - display_name = "Data Conditional Router" + display_name = "Condition" description = "Route Data object(s) based on a condition applied to a specified key, including boolean validation." icon = "split" beta = True name = "DataConditionalRouter" + legacy = True inputs = [ DataInput( @@ -26,14 +27,14 @@ class DataConditionalRouterComponent(Component): ), DropdownInput( name="operator", - display_name="Comparison Operator", + display_name="Operator", options=["equals", "not equals", "contains", "starts with", "ends with", "boolean validator"], info="The operator to apply for comparing the values. 'boolean validator' treats the value as a boolean.", value="equals", ), MessageTextInput( name="compare_value", - display_name="Compare Value", + display_name="Match Text", info="The value to compare against (not used for boolean validator)", ), ] diff --git a/src/backend/base/langflow/components/prototypes/flow_tool.py b/src/backend/base/langflow/components/logic/flow_tool.py similarity index 99% rename from src/backend/base/langflow/components/prototypes/flow_tool.py rename to src/backend/base/langflow/components/logic/flow_tool.py index 60da84257..2c835a51f 100644 --- a/src/backend/base/langflow/components/prototypes/flow_tool.py +++ b/src/backend/base/langflow/components/logic/flow_tool.py @@ -20,6 +20,7 @@ class FlowToolComponent(LCToolComponent): trace_type = "tool" name = "FlowTool" beta = True + icon = "hammer" def get_flow_names(self) -> list[str]: flow_datas = self.list_flows() diff --git a/src/backend/base/langflow/components/prototypes/listen.py b/src/backend/base/langflow/components/logic/listen.py similarity index 97% rename from src/backend/base/langflow/components/prototypes/listen.py rename to src/backend/base/langflow/components/logic/listen.py index e75ec070b..e2e6afa48 100644 --- a/src/backend/base/langflow/components/prototypes/listen.py +++ b/src/backend/base/langflow/components/logic/listen.py @@ -7,6 +7,7 @@ class ListenComponent(CustomComponent): description = "A component to listen for a notification." name = "Listen" beta: bool = True + icon = "Radio" def build_config(self): return { diff --git a/src/backend/base/langflow/components/prototypes/notify.py b/src/backend/base/langflow/components/logic/notify.py similarity index 100% rename from src/backend/base/langflow/components/prototypes/notify.py rename to src/backend/base/langflow/components/logic/notify.py diff --git a/src/backend/base/langflow/components/prototypes/pass_message.py b/src/backend/base/langflow/components/logic/pass_message.py similarity index 100% rename from src/backend/base/langflow/components/prototypes/pass_message.py rename to src/backend/base/langflow/components/logic/pass_message.py diff --git a/src/backend/base/langflow/components/prototypes/run_flow.py b/src/backend/base/langflow/components/logic/run_flow.py similarity index 98% rename from src/backend/base/langflow/components/prototypes/run_flow.py rename to src/backend/base/langflow/components/logic/run_flow.py index 818c694a1..8665f0063 100644 --- a/src/backend/base/langflow/components/prototypes/run_flow.py +++ b/src/backend/base/langflow/components/logic/run_flow.py @@ -16,6 +16,8 @@ class RunFlowComponent(Component): description = "A component to run a flow." name = "RunFlow" beta: bool = True + legacy: bool = True + icon = "workflow" def get_flow_names(self) -> list[str]: flow_data = self.list_flows() diff --git a/src/backend/base/langflow/components/prototypes/sub_flow.py b/src/backend/base/langflow/components/logic/sub_flow.py similarity index 99% rename from src/backend/base/langflow/components/prototypes/sub_flow.py rename to src/backend/base/langflow/components/logic/sub_flow.py index 7c30647af..2fb0fe958 100644 --- a/src/backend/base/langflow/components/prototypes/sub_flow.py +++ b/src/backend/base/langflow/components/logic/sub_flow.py @@ -16,6 +16,7 @@ class SubFlowComponent(Component): description = "Generates a Component from a Flow, with all of its inputs, and " name = "SubFlow" beta: bool = True + icon = "Workflow" def get_flow_names(self) -> list[str]: flow_data = self.list_flows() diff --git a/src/backend/base/langflow/components/mem0/__init__.py b/src/backend/base/langflow/components/mem0/__init__.py new file mode 100644 index 000000000..6337d0cfc --- /dev/null +++ b/src/backend/base/langflow/components/mem0/__init__.py @@ -0,0 +1,5 @@ +from .mem0_chat_memory import Mem0MemoryComponent + +__all__ = [ + "Mem0MemoryComponent", +] diff --git a/src/backend/base/langflow/components/memories/mem0_chat_memory.py b/src/backend/base/langflow/components/mem0/mem0_chat_memory.py similarity index 100% rename from src/backend/base/langflow/components/memories/mem0_chat_memory.py rename to src/backend/base/langflow/components/mem0/mem0_chat_memory.py diff --git a/src/backend/base/langflow/components/memories/__init__.py b/src/backend/base/langflow/components/memories/__init__.py index e69de29bb..9432cdf34 100644 --- a/src/backend/base/langflow/components/memories/__init__.py +++ b/src/backend/base/langflow/components/memories/__init__.py @@ -0,0 +1,15 @@ +from .astra_db import AstraDBChatMemory +from .cassandra import CassandraChatMemory +from .memory import MemoryComponent +from .redis import RedisIndexChatMemory +from .store_message import StoreMessageComponent +from .zep import ZepChatMemory + +__all__ = [ + "AstraDBChatMemory", + "CassandraChatMemory", + "MemoryComponent", + "RedisIndexChatMemory", + "ZepChatMemory", + "StoreMessageComponent", +] diff --git a/src/backend/base/langflow/components/helpers/memory.py b/src/backend/base/langflow/components/memories/memory.py similarity index 93% rename from src/backend/base/langflow/components/helpers/memory.py rename to src/backend/base/langflow/components/memories/memory.py index 988b92c16..216021b92 100644 --- a/src/backend/base/langflow/components/helpers/memory.py +++ b/src/backend/base/langflow/components/memories/memory.py @@ -70,9 +70,8 @@ class MemoryComponent(Component): ] outputs = [ - Output(display_name="Messages (Data)", name="messages", method="retrieve_messages"), - Output(display_name="Messages (Text)", name="messages_text", method="retrieve_messages_as_text"), - Output(display_name="Memory", name="lc_memory", method="build_lc_memory"), + Output(display_name="Data", name="messages", method="retrieve_messages"), + Output(display_name="Text", name="messages_text", method="retrieve_messages_as_text"), ] def retrieve_messages(self) -> Data: diff --git a/src/backend/base/langflow/components/helpers/store_message.py b/src/backend/base/langflow/components/memories/store_message.py similarity index 100% rename from src/backend/base/langflow/components/helpers/store_message.py rename to src/backend/base/langflow/components/memories/store_message.py diff --git a/src/backend/base/langflow/components/memories/zep.py b/src/backend/base/langflow/components/memories/zep.py index 90060e694..d9a4905cb 100644 --- a/src/backend/base/langflow/components/memories/zep.py +++ b/src/backend/base/langflow/components/memories/zep.py @@ -7,6 +7,7 @@ class ZepChatMemory(LCChatMemoryComponent): display_name = "Zep Chat Memory" description = "Retrieves and store chat messages from Zep." name = "ZepChatMemory" + icon = "ZepMemory" inputs = [ MessageTextInput(name="url", display_name="Zep URL", info="URL of the Zep instance."), diff --git a/src/backend/base/langflow/components/models/__init__.py b/src/backend/base/langflow/components/models/__init__.py index 87a3be912..974f32a9c 100644 --- a/src/backend/base/langflow/components/models/__init__.py +++ b/src/backend/base/langflow/components/models/__init__.py @@ -5,7 +5,12 @@ from .azure_openai import AzureChatOpenAIComponent from .baidu_qianfan_chat import QianfanChatEndpointComponent from .cohere import CohereComponent from .google_generative_ai import GoogleGenerativeAIComponent +from .groq import GroqModel from .huggingface import HuggingFaceEndpointsComponent +from .lmstudiomodel import LMStudioModelComponent +from .maritalk import MaritalkModelComponent +from .mistral import MistralAIModelComponent +from .nvidia import NVIDIAModelComponent from .ollama import ChatOllamaComponent from .openai import OpenAIModelComponent from .perplexity import PerplexityComponent @@ -20,9 +25,13 @@ __all__ = [ "ChatVertexAIComponent", "CohereComponent", "GoogleGenerativeAIComponent", + "GroqModel", "HuggingFaceEndpointsComponent", + "LMStudioModelComponent", + "MaritalkModelComponent", + "MistralAIModelComponent", + "NVIDIAModelComponent", "OpenAIModelComponent", "PerplexityComponent", "QianfanChatEndpointComponent", - "base", ] diff --git a/src/backend/base/langflow/components/nvidia/__init__.py b/src/backend/base/langflow/components/nvidia/__init__.py new file mode 100644 index 000000000..1e6f375b2 --- /dev/null +++ b/src/backend/base/langflow/components/nvidia/__init__.py @@ -0,0 +1,3 @@ +from .nvidia_rerank import NvidiaRerankComponent + +__all__ = ["NvidiaRerankComponent"] diff --git a/src/backend/base/langflow/components/retrievers/nvidia_rerank.py b/src/backend/base/langflow/components/nvidia/nvidia_rerank.py similarity index 100% rename from src/backend/base/langflow/components/retrievers/nvidia_rerank.py rename to src/backend/base/langflow/components/nvidia/nvidia_rerank.py diff --git a/src/backend/base/langflow/components/output_parsers/__init__.py b/src/backend/base/langflow/components/output_parsers/__init__.py index 09d102a00..e69de29bb 100644 --- a/src/backend/base/langflow/components/output_parsers/__init__.py +++ b/src/backend/base/langflow/components/output_parsers/__init__.py @@ -1,3 +0,0 @@ -from .output_parser import OutputParserComponent - -__all__ = ["OutputParserComponent"] diff --git a/src/backend/base/langflow/components/processing/__init__.py b/src/backend/base/langflow/components/processing/__init__.py new file mode 100644 index 000000000..7fd2f3359 --- /dev/null +++ b/src/backend/base/langflow/components/processing/__init__.py @@ -0,0 +1,25 @@ +from .combine_text import CombineTextComponent +from .create_data import CreateDataComponent +from .extract_key import ExtractDataKeyComponent +from .filter_data_values import DataFilterComponent +from .json_cleaner import JSONCleaner +from .merge_data import MergeDataComponent +from .message_to_data import MessageToDataComponent +from .parse_data import ParseDataComponent +from .parse_json_data import ParseJSONDataComponent +from .select_data import SelectDataComponent +from .update_data import UpdateDataComponent + +__all__ = [ + "CreateDataComponent", + "ExtractDataKeyComponent", + "DataFilterComponent", + "MergeDataComponent", + "MessageToDataComponent", + "ParseDataComponent", + "SelectDataComponent", + "UpdateDataComponent", + "ParseJSONDataComponent", + "JSONCleaner", + "CombineTextComponent", +] diff --git a/src/backend/base/langflow/components/helpers/combine_text.py b/src/backend/base/langflow/components/processing/combine_text.py similarity index 100% rename from src/backend/base/langflow/components/helpers/combine_text.py rename to src/backend/base/langflow/components/processing/combine_text.py diff --git a/src/backend/base/langflow/components/prototypes/create_data.py b/src/backend/base/langflow/components/processing/create_data.py similarity index 100% rename from src/backend/base/langflow/components/prototypes/create_data.py rename to src/backend/base/langflow/components/processing/create_data.py diff --git a/src/backend/base/langflow/components/helpers/extract_key.py b/src/backend/base/langflow/components/processing/extract_key.py similarity index 100% rename from src/backend/base/langflow/components/helpers/extract_key.py rename to src/backend/base/langflow/components/processing/extract_key.py diff --git a/src/backend/base/langflow/components/helpers/filter_data.py b/src/backend/base/langflow/components/processing/filter_data.py similarity index 100% rename from src/backend/base/langflow/components/helpers/filter_data.py rename to src/backend/base/langflow/components/processing/filter_data.py diff --git a/src/backend/base/langflow/components/helpers/filter_data_values.py b/src/backend/base/langflow/components/processing/filter_data_values.py similarity index 98% rename from src/backend/base/langflow/components/helpers/filter_data_values.py rename to src/backend/base/langflow/components/processing/filter_data_values.py index 19e88367f..998bdae7d 100644 --- a/src/backend/base/langflow/components/helpers/filter_data_values.py +++ b/src/backend/base/langflow/components/processing/filter_data_values.py @@ -6,7 +6,7 @@ from langflow.schema import Data class DataFilterComponent(Component): - display_name = "Filter Data Values" + display_name = "Filter Values" description = ( "Filter a list of data items based on a specified key, filter value," " and comparison operator. Check advanced options to select match comparision." diff --git a/src/backend/base/langflow/components/prototypes/json_cleaner.py b/src/backend/base/langflow/components/processing/json_cleaner.py similarity index 99% rename from src/backend/base/langflow/components/prototypes/json_cleaner.py rename to src/backend/base/langflow/components/processing/json_cleaner.py index b1b7dcb85..d9d6051c8 100644 --- a/src/backend/base/langflow/components/prototypes/json_cleaner.py +++ b/src/backend/base/langflow/components/processing/json_cleaner.py @@ -9,12 +9,12 @@ from langflow.template import Output class JSONCleaner(Component): + icon = "braces" display_name = "JSON Cleaner" description = ( "Cleans the messy and sometimes incorrect JSON strings produced by LLMs " "so that they are fully compliant with the JSON spec." ) - icon = "custom_components" inputs = [ MessageTextInput( diff --git a/src/backend/base/langflow/components/helpers/merge_data.py b/src/backend/base/langflow/components/processing/merge_data.py similarity index 100% rename from src/backend/base/langflow/components/helpers/merge_data.py rename to src/backend/base/langflow/components/processing/merge_data.py diff --git a/src/backend/base/langflow/components/helpers/message_to_data.py b/src/backend/base/langflow/components/processing/message_to_data.py similarity index 87% rename from src/backend/base/langflow/components/helpers/message_to_data.py rename to src/backend/base/langflow/components/processing/message_to_data.py index 44ad8ece2..f5303deb5 100644 --- a/src/backend/base/langflow/components/helpers/message_to_data.py +++ b/src/backend/base/langflow/components/processing/message_to_data.py @@ -28,10 +28,7 @@ class MessageToDataComponent(Component): def convert_message_to_data(self) -> Data: if isinstance(self.message, Message): # Convert Message to Data - data = Data(data=self.message.data) - - self.status = "Successfully converted Message to Data" - return data + return Data(data=self.message.data) msg = "Error converting Message to Data: Input must be a Message object" logger.opt(exception=True).debug(msg) diff --git a/src/backend/base/langflow/components/helpers/parse_data.py b/src/backend/base/langflow/components/processing/parse_data.py similarity index 100% rename from src/backend/base/langflow/components/helpers/parse_data.py rename to src/backend/base/langflow/components/processing/parse_data.py diff --git a/src/backend/base/langflow/components/helpers/parse_json_data.py b/src/backend/base/langflow/components/processing/parse_json_data.py similarity index 99% rename from src/backend/base/langflow/components/helpers/parse_json_data.py rename to src/backend/base/langflow/components/processing/parse_json_data.py index e6cb92cb1..35b3ced69 100644 --- a/src/backend/base/langflow/components/helpers/parse_json_data.py +++ b/src/backend/base/langflow/components/processing/parse_json_data.py @@ -17,6 +17,7 @@ class ParseJSONDataComponent(Component): description = "Convert and extract JSON fields." icon = "braces" name = "ParseJSONData" + legacy: bool = True inputs = [ HandleInput( diff --git a/src/backend/base/langflow/components/prototypes/select_data.py b/src/backend/base/langflow/components/processing/select_data.py similarity index 100% rename from src/backend/base/langflow/components/prototypes/select_data.py rename to src/backend/base/langflow/components/processing/select_data.py diff --git a/src/backend/base/langflow/components/prototypes/update_data.py b/src/backend/base/langflow/components/processing/update_data.py similarity index 99% rename from src/backend/base/langflow/components/prototypes/update_data.py rename to src/backend/base/langflow/components/processing/update_data.py index 08e191ce8..007d6d721 100644 --- a/src/backend/base/langflow/components/prototypes/update_data.py +++ b/src/backend/base/langflow/components/processing/update_data.py @@ -15,7 +15,7 @@ from langflow.schema.dotdict import dotdict class UpdateDataComponent(Component): - display_name: str = "Update data" + display_name: str = "Update Data" description: str = "Dynamically update or append data with the specified fields." name: str = "UpdateData" MAX_FIELDS = 15 # Define a constant for maximum number of fields diff --git a/src/backend/base/langflow/components/prompts/__init__.py b/src/backend/base/langflow/components/prompts/__init__.py index f4a218849..89e6cec0f 100644 --- a/src/backend/base/langflow/components/prompts/__init__.py +++ b/src/backend/base/langflow/components/prompts/__init__.py @@ -1,4 +1,3 @@ -from .langchain_hub import LangChainHubPromptComponent from .prompt import PromptComponent -__all__ = ["LangChainHubPromptComponent", "PromptComponent"] +__all__ = ["PromptComponent"] diff --git a/src/backend/base/langflow/components/prototypes/__init__.py b/src/backend/base/langflow/components/prototypes/__init__.py index 51b9fa26d..8ad61e02b 100644 --- a/src/backend/base/langflow/components/prototypes/__init__.py +++ b/src/backend/base/langflow/components/prototypes/__init__.py @@ -1,27 +1,5 @@ -from .conditional_router import ConditionalRouterComponent -from .create_data import CreateDataComponent -from .flow_tool import FlowToolComponent -from .listen import ListenComponent -from .notify import NotifyComponent -from .pass_message import PassMessageComponent from .python_function import PythonFunctionComponent -from .run_flow import RunFlowComponent -from .runnable_executor import RunnableExecComponent -from .sql_executor import SQLExecutorComponent -from .sub_flow import SubFlowComponent -from .update_data import UpdateDataComponent __all__ = [ - "ConditionalRouterComponent", - "CreateDataComponent", - "FlowToolComponent", - "ListenComponent", - "NotifyComponent", - "PassMessageComponent", "PythonFunctionComponent", - "RunFlowComponent", - "RunnableExecComponent", - "SQLExecutorComponent", - "SubFlowComponent", - "UpdateDataComponent", ] diff --git a/src/backend/base/langflow/components/prototypes/python_function.py b/src/backend/base/langflow/components/prototypes/python_function.py index 507c3b564..cb415586e 100644 --- a/src/backend/base/langflow/components/prototypes/python_function.py +++ b/src/backend/base/langflow/components/prototypes/python_function.py @@ -14,7 +14,7 @@ class PythonFunctionComponent(Component): description = "Define and execute a Python function that returns a Data object or a Message." icon = "Python" name = "PythonFunction" - beta = True + legacy = True inputs = [ CodeInput( diff --git a/src/backend/base/langflow/components/retrievers/__init__.py b/src/backend/base/langflow/components/retrievers/__init__.py index dfafe0806..f5de9b4cd 100644 --- a/src/backend/base/langflow/components/retrievers/__init__.py +++ b/src/backend/base/langflow/components/retrievers/__init__.py @@ -1,13 +1,9 @@ from .amazon_kendra import AmazonKendraRetrieverComponent from .metal import MetalRetrieverComponent from .multi_query import MultiQueryRetrieverComponent -from .vectara_self_query import VectaraSelfQueryRetriverComponent -from .vector_store import VectoStoreRetrieverComponent __all__ = [ "AmazonKendraRetrieverComponent", "MetalRetrieverComponent", "MultiQueryRetrieverComponent", - "VectaraSelfQueryRetriverComponent", - "VectoStoreRetrieverComponent", ] diff --git a/src/backend/base/langflow/components/textsplitters/__init__.py b/src/backend/base/langflow/components/textsplitters/__init__.py index 002750fda..e69de29bb 100644 --- a/src/backend/base/langflow/components/textsplitters/__init__.py +++ b/src/backend/base/langflow/components/textsplitters/__init__.py @@ -1,13 +0,0 @@ -from .character import CharacterTextSplitterComponent -from .language_recursive import LanguageRecursiveTextSplitterComponent -from .language_semantic import SemanticTextSplitterComponent -from .natural_language import NaturalLanguageTextSplitterComponent -from .recursive_character import RecursiveCharacterTextSplitterComponent - -__all__ = [ - "CharacterTextSplitterComponent", - "LanguageRecursiveTextSplitterComponent", - "NaturalLanguageTextSplitterComponent", - "RecursiveCharacterTextSplitterComponent", - "SemanticTextSplitterComponent", -] diff --git a/src/backend/base/langflow/components/toolkits/__init__.py b/src/backend/base/langflow/components/toolkits/__init__.py index 13bbcb328..e69de29bb 100644 --- a/src/backend/base/langflow/components/toolkits/__init__.py +++ b/src/backend/base/langflow/components/toolkits/__init__.py @@ -1,9 +0,0 @@ -from .composio_api import ComposioAPIComponent -from .metaphor import MetaphorToolkit -from .vector_store_info import VectorStoreInfoComponent - -__all__ = [ - "ComposioAPIComponent", - "MetaphorToolkit", - "VectorStoreInfoComponent", -] diff --git a/src/backend/base/langflow/components/tools/__init__.py b/src/backend/base/langflow/components/tools/__init__.py index a5b8a0d6c..1487e3a9c 100644 --- a/src/backend/base/langflow/components/tools/__init__.py +++ b/src/backend/base/langflow/components/tools/__init__.py @@ -8,6 +8,7 @@ from .duck_duck_go_search_run import DuckDuckGoSearchComponent from .glean_search_api import GleanSearchAPIComponent from .google_search_api import GoogleSearchAPIComponent from .google_serper_api import GoogleSerperAPIComponent +from .metaphor import MetaphorToolkit from .python_code_structured_tool import PythonCodeStructuredTool from .python_repl import PythonREPLToolComponent from .retriever import RetrieverToolComponent @@ -33,11 +34,12 @@ __all__ = [ "GleanSearchAPIComponent", "GoogleSearchAPIComponent", "GoogleSerperAPIComponent", + "MetaphorToolkit", "PythonCodeStructuredTool", "PythonREPLToolComponent", "RetrieverToolComponent", - "SearXNGToolComponent", "SearchAPIComponent", + "SearXNGToolComponent", "SerpAPIComponent", "TavilySearchToolComponent", "WikipediaAPIComponent", diff --git a/src/backend/base/langflow/components/toolkits/metaphor.py b/src/backend/base/langflow/components/tools/metaphor.py similarity index 91% rename from src/backend/base/langflow/components/toolkits/metaphor.py rename to src/backend/base/langflow/components/tools/metaphor.py index d2ce8010b..ad4c97159 100644 --- a/src/backend/base/langflow/components/toolkits/metaphor.py +++ b/src/backend/base/langflow/components/tools/metaphor.py @@ -7,15 +7,16 @@ from langflow.io import BoolInput, IntInput, Output, SecretStrInput class MetaphorToolkit(Component): - display_name = "Metaphor" - description = "Metaphor Toolkit for search and content retrieval" + display_name = "Exa Search" + description = "Exa Search toolkit for search and content retrieval" documentation = "https://python.langchain.com/docs/integrations/tools/metaphor_search" beta = True + name = "ExaSearch" inputs = [ SecretStrInput( name="metaphor_api_key", - display_name="Metaphor API Key", + display_name="Exa Search API Key", password=True, ), BoolInput( diff --git a/src/backend/base/langflow/components/tools/search_api.py b/src/backend/base/langflow/components/tools/search_api.py index 2bb045d05..f6c24936e 100644 --- a/src/backend/base/langflow/components/tools/search_api.py +++ b/src/backend/base/langflow/components/tools/search_api.py @@ -30,7 +30,7 @@ class SearchAPIComponent(LCToolComponent): class SearchAPISchema(BaseModel): query: str = Field(..., description="The search query") - params: dict[str, Any] | None = Field(default_factory=dict, description="Additional search parameters") + params: dict[str, Any] = Field(default_factory=dict, description="Additional search parameters") max_results: int = Field(5, description="Maximum number of results to return") max_snippet_length: int = Field(100, description="Maximum length of each result snippet") diff --git a/src/backend/base/langflow/components/tools/wolfram_alpha_api.py b/src/backend/base/langflow/components/tools/wolfram_alpha_api.py index 6e30781e3..94674442e 100644 --- a/src/backend/base/langflow/components/tools/wolfram_alpha_api.py +++ b/src/backend/base/langflow/components/tools/wolfram_alpha_api.py @@ -7,14 +7,15 @@ from langflow.schema import Data class WolframAlphaAPIComponent(LCToolComponent): - display_name = "WolframAlphaAPI" - description = "Call Wolfram Alpha API." + display_name = "WolframAlpha API" + description = """Enables queries to Wolfram Alpha for computational data, facts, and calculations across various \ +topics, delivering structured responses. Example query: 'What is the population of France?'""" name = "WolframAlphaAPI" inputs = [ MultilineInput( name="input_value", - display_name="Input", + display_name="Input Query", ), SecretStrInput(name="app_id", display_name="App ID", required=True), ] diff --git a/src/backend/base/langflow/components/tools/yahoo_finance.py b/src/backend/base/langflow/components/tools/yahoo_finance.py index fd322fedb..6974843bb 100644 --- a/src/backend/base/langflow/components/tools/yahoo_finance.py +++ b/src/backend/base/langflow/components/tools/yahoo_finance.py @@ -13,7 +13,7 @@ from langflow.schema import Data class YfinanceToolComponent(LCToolComponent): - display_name = "Yahoo Finance Tool" + display_name = "Yahoo Finance" description = "Access financial data and market information using Yahoo Finance." icon = "trending-up" name = "YahooFinanceTool" @@ -54,7 +54,7 @@ class YfinanceToolComponent(LCToolComponent): class YahooFinanceSchema(BaseModel): symbol: str = Field(..., description="The stock symbol to retrieve data for.") method: str = Field("get_info", description="The type of data to retrieve.") - num_news: int | None = Field(5, description="The number of news articles to retrieve.") + num_news: int = Field(5, description="The number of news articles to retrieve.") def run_model(self) -> list[Data]: return self._yahoo_finance_tool( diff --git a/src/backend/base/langflow/components/unstructured/__init__.py b/src/backend/base/langflow/components/unstructured/__init__.py new file mode 100644 index 000000000..a9bceaabc --- /dev/null +++ b/src/backend/base/langflow/components/unstructured/__init__.py @@ -0,0 +1,3 @@ +from .unstructured import UnstructuredComponent + +__all__ = ["UnstructuredComponent"] diff --git a/src/backend/base/langflow/components/documentloaders/unstructured.py b/src/backend/base/langflow/components/unstructured/unstructured.py similarity index 100% rename from src/backend/base/langflow/components/documentloaders/unstructured.py rename to src/backend/base/langflow/components/unstructured/unstructured.py diff --git a/src/backend/base/langflow/components/vectara/__init__.py b/src/backend/base/langflow/components/vectara/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/base/langflow/components/vectorstores/__init__.py b/src/backend/base/langflow/components/vectorstores/__init__.py index 11af275d7..7ac64d890 100644 --- a/src/backend/base/langflow/components/vectorstores/__init__.py +++ b/src/backend/base/langflow/components/vectorstores/__init__.py @@ -1,3 +1,49 @@ from .astradb import AstraVectorStoreComponent +from .astradb_graph import AstraGraphVectorStoreComponent +from .cassandra import CassandraVectorStoreComponent +from .cassandra_graph import CassandraGraphVectorStoreComponent +from .chroma import ChromaVectorStoreComponent +from .clickhouse import ClickhouseVectorStoreComponent +from .couchbase import CouchbaseVectorStoreComponent +from .elasticsearch import ElasticsearchVectorStoreComponent +from .faiss import FaissVectorStoreComponent +from .hcd import HCDVectorStoreComponent +from .milvus import MilvusVectorStoreComponent +from .mongodb_atlas import MongoVectorStoreComponent +from .opensearch import OpenSearchVectorStoreComponent +from .pgvector import PGVectorStoreComponent +from .pinecone import PineconeVectorStoreComponent +from .qdrant import QdrantVectorStoreComponent +from .redis import RedisVectorStoreComponent +from .supabase import SupabaseVectorStoreComponent +from .upstash import UpstashVectorStoreComponent +from .vectara import VectaraVectorStoreComponent +from .vectara_rag import VectaraRagComponent +from .vectara_self_query import VectaraSelfQueryRetriverComponent +from .weaviate import WeaviateVectorStoreComponent -__all__ = ["AstraVectorStoreComponent"] +__all__ = [ + "AstraGraphVectorStoreComponent", + "AstraVectorStoreComponent", + "CassandraGraphVectorStoreComponent", + "CassandraVectorStoreComponent", + "ChromaVectorStoreComponent", + "ClickhouseVectorStoreComponent", + "CouchbaseVectorStoreComponent", + "ElasticsearchVectorStoreComponent", + "FaissVectorStoreComponent", + "HCDVectorStoreComponent", + "MilvusVectorStoreComponent", + "MongoVectorStoreComponent", + "OpenSearchVectorStoreComponent", + "PGVectorStoreComponent", + "PineconeVectorStoreComponent", + "QdrantVectorStoreComponent", + "RedisVectorStoreComponent", + "SupabaseVectorStoreComponent", + "UpstashVectorStoreComponent", + "VectaraVectorStoreComponent", + "VectaraRagComponent", + "VectaraSelfQueryRetriverComponent", + "WeaviateVectorStoreComponent", +] diff --git a/src/backend/base/langflow/components/retrievers/vectara_self_query.py b/src/backend/base/langflow/components/vectorstores/vectara_self_query.py similarity index 99% rename from src/backend/base/langflow/components/retrievers/vectara_self_query.py rename to src/backend/base/langflow/components/vectorstores/vectara_self_query.py index a2b639a6a..d53d499a3 100644 --- a/src/backend/base/langflow/components/retrievers/vectara_self_query.py +++ b/src/backend/base/langflow/components/vectorstores/vectara_self_query.py @@ -18,6 +18,7 @@ class VectaraSelfQueryRetriverComponent(CustomComponent): documentation = "https://python.langchain.com/docs/integrations/retrievers/self_query/vectara_self_query" name = "VectaraSelfQueryRetriver" icon = "Vectara" + legacy = True field_config = { "code": {"show": True}, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Agent Flow.json b/src/backend/base/langflow/initial_setup/starter_projects/Agent Flow.json index 13f4dec60..27c223d01 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Agent Flow.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Agent Flow.json @@ -1089,7 +1089,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from langchain_core.tools import StructuredTool\n\nfrom langflow.base.agents.agent import LCToolsAgentComponent\nfrom langflow.base.models.model_input_constants import ALL_PROVIDER_FIELDS, MODEL_PROVIDERS_DICT\nfrom langflow.components.agents.tool_calling import ToolCallingAgentComponent\nfrom langflow.components.helpers import CurrentDateComponent\nfrom langflow.components.helpers.memory import MemoryComponent\nfrom langflow.io import BoolInput, DropdownInput, MultilineInput, Output\nfrom langflow.schema.dotdict import dotdict\nfrom langflow.schema.message import Message\n\n\ndef set_advanced_true(component_input):\n component_input.advanced = True\n return component_input\n\n\nclass AgentComponent(ToolCallingAgentComponent):\n display_name: str = \"Agent\"\n description: str = \"Define the agent's instructions, then enter a task to complete using tools.\"\n icon = \"bot\"\n beta = True\n name = \"Agent\"\n\n memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs]\n\n inputs = [\n DropdownInput(\n name=\"agent_llm\",\n display_name=\"Model Provider\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"OpenAI\",\n real_time_refresh=True,\n input_types=[],\n ),\n *MODEL_PROVIDERS_DICT[\"OpenAI\"][\"inputs\"],\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Agent Instructions\",\n info=\"Initial instructions and context provided to guide the agent's behavior.\",\n value=\"You are a helpful assistant that can use tools to answer questions and perform tasks.\",\n advanced=False,\n ),\n *LCToolsAgentComponent._base_inputs,\n *memory_inputs,\n BoolInput(\n name=\"add_current_date_tool\",\n display_name=\"Add tool Current Date\",\n advanced=True,\n info=\"If true, will add a tool to the agent that returns the current date.\",\n value=True,\n ),\n ]\n outputs = [Output(name=\"response\", display_name=\"Response\", method=\"message_response\")]\n\n async def message_response(self) -> Message:\n llm_model = self.get_llm()\n if llm_model is None:\n msg = \"No language model selected\"\n raise ValueError(msg)\n self.chat_history = self.get_memory_data()\n\n if self.add_current_date_tool:\n if not isinstance(self.tools, list): # type: ignore[has-type]\n self.tools = []\n # Convert CurrentDateComponent to a StructuredTool\n current_date_tool = CurrentDateComponent().to_toolkit()[0]\n if isinstance(current_date_tool, StructuredTool):\n self.tools.append(current_date_tool)\n else:\n msg = \"CurrentDateComponent must be converted to a StructuredTool\"\n raise ValueError(msg)\n\n if not self.tools:\n msg = \"Tools are required to run the agent.\"\n raise ValueError(msg)\n self.set(\n llm=llm_model,\n tools=self.tools,\n chat_history=self.chat_history,\n input_value=self.input_value,\n system_prompt=self.system_prompt,\n )\n agent = self.create_agent_runnable()\n return await self.run_agent(agent)\n\n def get_memory_data(self):\n memory_kwargs = {\n component_input.name: getattr(self, f\"{component_input.name}\") for component_input in self.memory_inputs\n }\n\n return MemoryComponent().set(**memory_kwargs).retrieve_messages()\n\n def get_llm(self):\n if isinstance(self.agent_llm, str):\n try:\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\", \"\")\n return self._build_llm_model(component_class, inputs, prefix)\n except Exception as e:\n msg = f\"Error building {self.agent_llm} language model\"\n raise ValueError(msg) from e\n return self.agent_llm\n\n def _build_llm_model(self, component, inputs, prefix=\"\"):\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n return component.set(**model_kwargs).build_model()\n\n def delete_fields(self, build_config: dotdict, fields: dict | list[str]) -> None:\n \"\"\"Delete specified fields from build_config.\"\"\"\n for field in fields:\n build_config.pop(field, None)\n\n def update_input_types(self, build_config: dotdict) -> dotdict:\n \"\"\"Update input types for all fields in build_config.\"\"\"\n for key, value in build_config.items():\n if isinstance(value, dict):\n if value.get(\"input_types\") is None:\n build_config[key][\"input_types\"] = []\n elif hasattr(value, \"input_types\") and value.input_types is None:\n value.input_types = []\n return build_config\n\n def update_build_config(self, build_config: dotdict, field_value: str, field_name: str | None = None) -> dotdict:\n if field_name == \"agent_llm\":\n # Define provider configurations as (fields_to_add, fields_to_delete)\n provider_configs: dict[str, tuple[dict, list[dict]]] = {\n provider: (\n MODEL_PROVIDERS_DICT[provider][\"fields\"],\n [\n MODEL_PROVIDERS_DICT[other_provider][\"fields\"]\n for other_provider in MODEL_PROVIDERS_DICT\n if other_provider != provider\n ],\n )\n for provider in MODEL_PROVIDERS_DICT\n }\n\n if field_value in provider_configs:\n fields_to_add, fields_to_delete = provider_configs[field_value]\n\n # Delete fields from other providers\n for fields in fields_to_delete:\n self.delete_fields(build_config, fields)\n\n # Add provider-specific fields\n if field_value == \"OpenAI\" and not any(field in build_config for field in fields_to_add):\n build_config.update(fields_to_add)\n else:\n build_config.update(fields_to_add)\n # Reset input types for agent_llm\n build_config[\"agent_llm\"][\"input_types\"] = []\n elif field_value == \"Custom\":\n # Delete all provider fields\n self.delete_fields(build_config, ALL_PROVIDER_FIELDS)\n # Update with custom component\n custom_component = DropdownInput(\n name=\"agent_llm\",\n display_name=\"Language Model\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"Custom\",\n real_time_refresh=True,\n input_types=[\"LanguageModel\"],\n )\n build_config.update({\"agent_llm\": custom_component.to_dict()})\n\n # Update input types for all fields\n build_config = self.update_input_types(build_config)\n\n # Validate required keys\n default_keys = [\n \"code\",\n \"_type\",\n \"agent_llm\",\n \"tools\",\n \"input_value\",\n \"add_current_date_tool\",\n \"system_prompt\",\n \"agent_description\",\n \"max_iterations\",\n \"handle_parsing_errors\",\n \"verbose\",\n ]\n missing_keys = [key for key in default_keys if key not in build_config]\n if missing_keys:\n msg = f\"Missing required keys in build_config: {missing_keys}\"\n raise ValueError(msg)\n\n return build_config\n" + "value": "from langchain_core.tools import StructuredTool\n\nfrom langflow.base.agents.agent import LCToolsAgentComponent\nfrom langflow.base.models.model_input_constants import ALL_PROVIDER_FIELDS, MODEL_PROVIDERS_DICT\nfrom langflow.components.helpers import CurrentDateComponent\nfrom langflow.components.langchain_utilities.tool_calling import ToolCallingAgentComponent\nfrom langflow.components.memories.memory import MemoryComponent\nfrom langflow.io import BoolInput, DropdownInput, MultilineInput, Output\nfrom langflow.schema.dotdict import dotdict\nfrom langflow.schema.message import Message\n\n\ndef set_advanced_true(component_input):\n component_input.advanced = True\n return component_input\n\n\nclass AgentComponent(ToolCallingAgentComponent):\n display_name: str = \"Agent\"\n description: str = \"Define the agent's instructions, then enter a task to complete using tools.\"\n icon = \"bot\"\n beta = True\n name = \"Agent\"\n\n memory_inputs = [set_advanced_true(component_input) for component_input in MemoryComponent().inputs]\n\n inputs = [\n DropdownInput(\n name=\"agent_llm\",\n display_name=\"Model Provider\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"OpenAI\",\n real_time_refresh=True,\n input_types=[],\n ),\n *MODEL_PROVIDERS_DICT[\"OpenAI\"][\"inputs\"],\n MultilineInput(\n name=\"system_prompt\",\n display_name=\"Agent Instructions\",\n info=\"Initial instructions and context provided to guide the agent's behavior.\",\n value=\"You are a helpful assistant that can use tools to answer questions and perform tasks.\",\n advanced=False,\n ),\n *LCToolsAgentComponent._base_inputs,\n *memory_inputs,\n BoolInput(\n name=\"add_current_date_tool\",\n display_name=\"Add tool Current Date\",\n advanced=True,\n info=\"If true, will add a tool to the agent that returns the current date.\",\n value=True,\n ),\n ]\n outputs = [Output(name=\"response\", display_name=\"Response\", method=\"message_response\")]\n\n async def message_response(self) -> Message:\n llm_model = self.get_llm()\n if llm_model is None:\n msg = \"No language model selected\"\n raise ValueError(msg)\n self.chat_history = self.get_memory_data()\n\n if self.add_current_date_tool:\n if not isinstance(self.tools, list): # type: ignore[has-type]\n self.tools = []\n # Convert CurrentDateComponent to a StructuredTool\n current_date_tool = CurrentDateComponent().to_toolkit()[0]\n if isinstance(current_date_tool, StructuredTool):\n self.tools.append(current_date_tool)\n else:\n msg = \"CurrentDateComponent must be converted to a StructuredTool\"\n raise ValueError(msg)\n\n if not self.tools:\n msg = \"Tools are required to run the agent.\"\n raise ValueError(msg)\n self.set(\n llm=llm_model,\n tools=self.tools,\n chat_history=self.chat_history,\n input_value=self.input_value,\n system_prompt=self.system_prompt,\n )\n agent = self.create_agent_runnable()\n return await self.run_agent(agent)\n\n def get_memory_data(self):\n memory_kwargs = {\n component_input.name: getattr(self, f\"{component_input.name}\") for component_input in self.memory_inputs\n }\n\n return MemoryComponent().set(**memory_kwargs).retrieve_messages()\n\n def get_llm(self):\n if isinstance(self.agent_llm, str):\n try:\n provider_info = MODEL_PROVIDERS_DICT.get(self.agent_llm)\n if provider_info:\n component_class = provider_info.get(\"component_class\")\n inputs = provider_info.get(\"inputs\")\n prefix = provider_info.get(\"prefix\", \"\")\n return self._build_llm_model(component_class, inputs, prefix)\n except Exception as e:\n msg = f\"Error building {self.agent_llm} language model\"\n raise ValueError(msg) from e\n return self.agent_llm\n\n def _build_llm_model(self, component, inputs, prefix=\"\"):\n model_kwargs = {input_.name: getattr(self, f\"{prefix}{input_.name}\") for input_ in inputs}\n return component.set(**model_kwargs).build_model()\n\n def delete_fields(self, build_config: dotdict, fields: dict | list[str]) -> None:\n \"\"\"Delete specified fields from build_config.\"\"\"\n for field in fields:\n build_config.pop(field, None)\n\n def update_input_types(self, build_config: dotdict) -> dotdict:\n \"\"\"Update input types for all fields in build_config.\"\"\"\n for key, value in build_config.items():\n if isinstance(value, dict):\n if value.get(\"input_types\") is None:\n build_config[key][\"input_types\"] = []\n elif hasattr(value, \"input_types\") and value.input_types is None:\n value.input_types = []\n return build_config\n\n def update_build_config(self, build_config: dotdict, field_value: str, field_name: str | None = None) -> dotdict:\n if field_name == \"agent_llm\":\n # Define provider configurations as (fields_to_add, fields_to_delete)\n provider_configs: dict[str, tuple[dict, list[dict]]] = {\n provider: (\n MODEL_PROVIDERS_DICT[provider][\"fields\"],\n [\n MODEL_PROVIDERS_DICT[other_provider][\"fields\"]\n for other_provider in MODEL_PROVIDERS_DICT\n if other_provider != provider\n ],\n )\n for provider in MODEL_PROVIDERS_DICT\n }\n\n if field_value in provider_configs:\n fields_to_add, fields_to_delete = provider_configs[field_value]\n\n # Delete fields from other providers\n for fields in fields_to_delete:\n self.delete_fields(build_config, fields)\n\n # Add provider-specific fields\n if field_value == \"OpenAI\" and not any(field in build_config for field in fields_to_add):\n build_config.update(fields_to_add)\n else:\n build_config.update(fields_to_add)\n # Reset input types for agent_llm\n build_config[\"agent_llm\"][\"input_types\"] = []\n elif field_value == \"Custom\":\n # Delete all provider fields\n self.delete_fields(build_config, ALL_PROVIDER_FIELDS)\n # Update with custom component\n custom_component = DropdownInput(\n name=\"agent_llm\",\n display_name=\"Language Model\",\n options=[*sorted(MODEL_PROVIDERS_DICT.keys()), \"Custom\"],\n value=\"Custom\",\n real_time_refresh=True,\n input_types=[\"LanguageModel\"],\n )\n build_config.update({\"agent_llm\": custom_component.to_dict()})\n\n # Update input types for all fields\n build_config = self.update_input_types(build_config)\n\n # Validate required keys\n default_keys = [\n \"code\",\n \"_type\",\n \"agent_llm\",\n \"tools\",\n \"input_value\",\n \"add_current_date_tool\",\n \"system_prompt\",\n \"agent_description\",\n \"max_iterations\",\n \"handle_parsing_errors\",\n \"verbose\",\n ]\n missing_keys = [key for key in default_keys if key not in build_config]\n if missing_keys:\n msg = f\"Missing required keys in build_config: {missing_keys}\"\n raise ValueError(msg)\n\n return build_config\n" }, "handle_parsing_errors": { "_input_type": "BoolInput", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json index 467072932..1257d0dd6 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Complex Agent.json @@ -4376,7 +4376,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] | None = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" + "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" }, "engine": { "advanced": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json index 2ee343195..25bad8554 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Document QA.json @@ -1333,7 +1333,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom zipfile import ZipFile, is_zipfile\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parallel_load_data, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, IntInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n \"\"\"Handles loading of individual or zipped text files.\n\n Processes multiple valid files within a zip archive if provided.\n\n Attributes:\n display_name: Display name of the component.\n description: Brief component description.\n icon: Icon to represent the component.\n name: Identifier for the component.\n inputs: Inputs required by the component.\n outputs: Output of the component after processing files.\n \"\"\"\n\n display_name = \"File\"\n description = \"Load a file to be used in your project.\"\n icon = \"file-text\"\n name = \"File\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=[*TEXT_FILE_TYPES, \"zip\"],\n info=f\"Supported file types: {', '.join([*TEXT_FILE_TYPES, 'zip'])}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n BoolInput(\n name=\"use_multithreading\",\n display_name=\"Use Multithreading\",\n advanced=True,\n info=\"If true, parallel processing will be enabled for zip files.\",\n ),\n IntInput(\n name=\"concurrency_multithreading\",\n display_name=\"Multithreading Concurrency\",\n advanced=True,\n info=\"The maximum number of workers to use, if concurrency is enabled\",\n value=4,\n ),\n ]\n\n outputs = [Output(display_name=\"Data\", name=\"data\", method=\"load_file\")]\n\n def load_file(self) -> Data:\n \"\"\"Load and parse file(s) from a zip archive.\n\n Raises:\n ValueError: If no file is uploaded or file path is invalid.\n\n Returns:\n Data: Parsed data from file(s).\n \"\"\"\n # Check if the file path is provided\n if not self.path:\n self.log(\"File path is missing.\")\n msg = \"Please upload a file for processing.\"\n\n raise ValueError(msg)\n\n resolved_path = Path(self.resolve_path(self.path))\n try:\n # Check if the file is a zip archive\n if is_zipfile(resolved_path):\n self.log(f\"Processing zip file: {resolved_path.name}.\")\n return self._process_zip_file(\n resolved_path,\n silent_errors=self.silent_errors,\n parallel=self.use_multithreading,\n )\n\n self.log(f\"Processing single file: {resolved_path.name}.\")\n return self._process_single_file(resolved_path, silent_errors=self.silent_errors)\n except FileNotFoundError:\n self.log(f\"File not found: {resolved_path.name}.\")\n raise\n\n def _process_zip_file(self, zip_path: Path, *, silent_errors: bool = False, parallel: bool = False) -> Data:\n \"\"\"Process text files within a zip archive.\n\n Args:\n zip_path: Path to the zip file.\n silent_errors: Suppresses errors if True.\n parallel: Enables parallel processing if True.\n\n Returns:\n list[Data]: Combined data from all valid files.\n\n Raises:\n ValueError: If no valid files found in the archive.\n \"\"\"\n data: list[Data] = []\n with ZipFile(zip_path, \"r\") as zip_file:\n # Filter file names based on extensions in TEXT_FILE_TYPES and ignore hidden files\n valid_files = [\n name\n for name in zip_file.namelist()\n if (\n any(name.endswith(ext) for ext in TEXT_FILE_TYPES)\n and not name.startswith(\"__MACOSX\")\n and not name.startswith(\".\")\n )\n ]\n\n # Raise an error if no valid files found\n if not valid_files:\n self.log(\"No valid files in the zip archive.\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return data # type: ignore[return-value]\n\n # Raise an error if no valid files found\n msg = \"No valid files in the zip archive.\"\n raise ValueError(msg)\n\n # Define a function to process each file\n def process_file(file_name, silent_errors=silent_errors):\n with NamedTemporaryFile(delete=False) as temp_file:\n temp_path = Path(temp_file.name).with_name(file_name)\n with zip_file.open(file_name) as file_content:\n temp_path.write_bytes(file_content.read())\n try:\n return self._process_single_file(temp_path, silent_errors=silent_errors)\n finally:\n temp_path.unlink()\n\n # Process files in parallel if specified\n if parallel:\n self.log(\n f\"Initializing parallel Thread Pool Executor with max workers: \"\n f\"{self.concurrency_multithreading}.\"\n )\n\n # Process files in parallel\n initial_data = parallel_load_data(\n valid_files,\n silent_errors=silent_errors,\n load_function=process_file,\n max_concurrency=self.concurrency_multithreading,\n )\n\n # Filter out empty data\n data = list(filter(None, initial_data))\n else:\n # Sequential processing\n data = [process_file(file_name) for file_name in valid_files]\n\n self.log(f\"Successfully processed zip file: {zip_path.name}.\")\n\n return data # type: ignore[return-value]\n\n def _process_single_file(self, file_path: Path, *, silent_errors: bool = False) -> Data:\n \"\"\"Process a single file.\n\n Args:\n file_path: Path to the file.\n silent_errors: Suppresses errors if True.\n\n Returns:\n Data: Parsed data from the file.\n\n Raises:\n ValueError: For unsupported file formats.\n \"\"\"\n # Check if the file type is supported\n if not any(file_path.suffix == ext for ext in [\".\" + f for f in TEXT_FILE_TYPES]):\n self.log(f\"Unsupported file type: {file_path.suffix}\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return Data()\n\n msg = f\"Unsupported file type: {file_path.suffix}\"\n raise ValueError(msg)\n\n try:\n # Parse the text file as appropriate\n data = parse_text_file_to_data(str(file_path), silent_errors=silent_errors) # type: ignore[assignment]\n if not data:\n data = Data()\n\n self.log(f\"Successfully processed file: {file_path.name}.\")\n except Exception as e:\n self.log(f\"Error processing file {file_path.name}: {e}\")\n\n # Return empty data if silent_errors is True\n if not silent_errors:\n raise\n\n data = Data()\n\n return data\n" + "value": "from pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom zipfile import ZipFile, is_zipfile\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parallel_load_data, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, IntInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n \"\"\"Handles loading of individual or zipped text files.\n\n Processes multiple valid files within a zip archive if provided.\n\n Attributes:\n display_name: Display name of the component.\n description: Brief component description.\n icon: Icon to represent the component.\n name: Identifier for the component.\n inputs: Inputs required by the component.\n outputs: Output of the component after processing files.\n \"\"\"\n\n display_name = \"File\"\n description = \"Load a file to be used in your project.\"\n icon = \"file-text\"\n name = \"File\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=[*TEXT_FILE_TYPES, \"zip\"],\n info=f\"Supported file types: {', '.join([*TEXT_FILE_TYPES, 'zip'])}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n BoolInput(\n name=\"use_multithreading\",\n display_name=\"Use Multithreading\",\n advanced=True,\n info=\"If true, parallel processing will be enabled for zip files.\",\n ),\n IntInput(\n name=\"concurrency_multithreading\",\n display_name=\"Multithreading Concurrency\",\n advanced=True,\n info=\"The maximum number of workers to use, if concurrency is enabled\",\n value=4,\n ),\n ]\n\n outputs = [Output(display_name=\"Data\", name=\"data\", method=\"load_file\")]\n\n def load_file(self) -> Data:\n \"\"\"Load and parse file(s) from a zip archive.\n\n Raises:\n ValueError: If no file is uploaded or file path is invalid.\n\n Returns:\n Data: Parsed data from file(s).\n \"\"\"\n # Check if the file path is provided\n if not self.path:\n self.log(\"File path is missing.\")\n msg = \"Please upload a file for processing.\"\n\n raise ValueError(msg)\n\n resolved_path = Path(self.resolve_path(self.path))\n try:\n # Check if the file is a zip archive\n if is_zipfile(resolved_path):\n self.log(f\"Processing zip file: {resolved_path.name}.\")\n\n return self._process_zip_file(\n resolved_path,\n silent_errors=self.silent_errors,\n parallel=self.use_multithreading,\n )\n\n self.log(f\"Processing single file: {resolved_path.name}.\")\n\n return self._process_single_file(resolved_path, silent_errors=self.silent_errors)\n except FileNotFoundError:\n self.log(f\"File not found: {resolved_path.name}.\")\n\n raise\n\n def _process_zip_file(self, zip_path: Path, *, silent_errors: bool = False, parallel: bool = False) -> Data:\n \"\"\"Process text files within a zip archive.\n\n Args:\n zip_path: Path to the zip file.\n silent_errors: Suppresses errors if True.\n parallel: Enables parallel processing if True.\n\n Returns:\n list[Data]: Combined data from all valid files.\n\n Raises:\n ValueError: If no valid files found in the archive.\n \"\"\"\n data: list[Data] = []\n with ZipFile(zip_path, \"r\") as zip_file:\n # Filter file names based on extensions in TEXT_FILE_TYPES and ignore hidden files\n valid_files = [\n name\n for name in zip_file.namelist()\n if (\n any(name.endswith(ext) for ext in TEXT_FILE_TYPES)\n and not name.startswith(\"__MACOSX\")\n and not name.startswith(\".\")\n )\n ]\n\n # Raise an error if no valid files found\n if not valid_files:\n self.log(\"No valid files in the zip archive.\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return data # type: ignore[return-value]\n\n # Raise an error if no valid files found\n msg = \"No valid files in the zip archive.\"\n raise ValueError(msg)\n\n # Define a function to process each file\n def process_file(file_name, silent_errors=silent_errors):\n with NamedTemporaryFile(delete=False) as temp_file:\n temp_path = Path(temp_file.name).with_name(file_name)\n with zip_file.open(file_name) as file_content:\n temp_path.write_bytes(file_content.read())\n try:\n return self._process_single_file(temp_path, silent_errors=silent_errors)\n finally:\n temp_path.unlink()\n\n # Process files in parallel if specified\n if parallel:\n self.log(\n f\"Initializing parallel Thread Pool Executor with max workers: \"\n f\"{self.concurrency_multithreading}.\"\n )\n\n # Process files in parallel\n initial_data = parallel_load_data(\n valid_files,\n silent_errors=silent_errors,\n load_function=process_file,\n max_concurrency=self.concurrency_multithreading,\n )\n\n # Filter out empty data\n data = list(filter(None, initial_data))\n else:\n # Sequential processing\n data = [process_file(file_name) for file_name in valid_files]\n\n self.log(f\"Successfully processed zip file: {zip_path.name}.\")\n\n return data # type: ignore[return-value]\n\n def _process_single_file(self, file_path: Path, *, silent_errors: bool = False) -> Data:\n \"\"\"Process a single file.\n\n Args:\n file_path: Path to the file.\n silent_errors: Suppresses errors if True.\n\n Returns:\n Data: Parsed data from the file.\n\n Raises:\n ValueError: For unsupported file formats.\n \"\"\"\n # Check if the file type is supported\n if not any(file_path.suffix == ext for ext in [\".\" + f for f in TEXT_FILE_TYPES]):\n self.log(f\"Unsupported file type: {file_path.suffix}\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return Data()\n\n msg = f\"Unsupported file type: {file_path.suffix}\"\n raise ValueError(msg)\n\n try:\n # Parse the text file as appropriate\n data = parse_text_file_to_data(str(file_path), silent_errors=silent_errors) # type: ignore[assignment]\n if not data:\n data = Data()\n\n self.log(f\"Successfully processed file: {file_path.name}.\")\n except Exception as e:\n self.log(f\"Error processing file {file_path.name}: {e}\")\n\n # Return empty data if silent_errors is True\n if not silent_errors:\n raise\n\n data = Data()\n\n return data\n" }, "concurrency_multithreading": { "_input_type": "IntInput", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json b/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json index cfef0752d..b9bd2246a 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Hierarchical Agent.json @@ -2865,7 +2865,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] | None = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" + "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" }, "engine": { "advanced": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json index 9a76b0a01..706042f07 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Memory Chatbot.json @@ -1145,7 +1145,7 @@ "outputs": [ { "cache": true, - "display_name": "Messages (Data)", + "display_name": "Data", "method": "retrieve_messages", "name": "messages", "selected": "Data", @@ -1156,7 +1156,7 @@ }, { "cache": true, - "display_name": "Messages (Text)", + "display_name": "Text", "method": "retrieve_messages_as_text", "name": "messages_text", "selected": "Message", @@ -1164,17 +1164,6 @@ "Message" ], "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Memory", - "method": "build_lc_memory", - "name": "lc_memory", - "selected": "BaseChatMemory", - "types": [ - "BaseChatMemory" - ], - "value": "__UNDEFINED__" } ], "pinned": false, @@ -1196,7 +1185,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from langchain.memory import ConversationBufferMemory\n\nfrom langflow.custom import Component\nfrom langflow.field_typing import BaseChatMemory\nfrom langflow.helpers.data import data_to_text\nfrom langflow.inputs import HandleInput\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import LCBuiltinChatMemory, get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages from Langflow tables or an external memory.\"\n icon = \"message-square-more\"\n name = \"Memory\"\n\n inputs = [\n HandleInput(\n name=\"memory\",\n display_name=\"External Memory\",\n input_types=[\"BaseChatMessageHistory\"],\n info=\"Retrieve messages from an external memory. If empty, it will use the Langflow tables.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Filter by sender type.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Filter by sender name.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. \"\n \"It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Messages (Data)\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Messages (Text)\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n Output(display_name=\"Memory\", name=\"lc_memory\", method=\"build_lc_memory\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n if self.memory:\n # override session_id\n self.memory.session_id = session_id\n\n stored = self.memory.messages\n # langchain memories are supposed to return messages in ascending order\n if order == \"DESC\":\n stored = stored[::-1]\n if n_messages:\n stored = stored[:n_messages]\n stored = [Message.from_lc_message(m) for m in stored]\n if sender:\n expected_type = MESSAGE_SENDER_AI if sender == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER\n stored = [m for m in stored if m.type == expected_type]\n else:\n stored = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = stored\n return stored\n\n def retrieve_messages_as_text(self) -> Message:\n stored_text = data_to_text(self.template, self.retrieve_messages())\n self.status = stored_text\n return Message(text=stored_text)\n\n def build_lc_memory(self) -> BaseChatMemory:\n chat_memory = self.memory or LCBuiltinChatMemory(flow_id=self.flow_id, session_id=self.session_id)\n return ConversationBufferMemory(chat_memory=chat_memory)\n" + "value": "from langchain.memory import ConversationBufferMemory\n\nfrom langflow.custom import Component\nfrom langflow.field_typing import BaseChatMemory\nfrom langflow.helpers.data import data_to_text\nfrom langflow.inputs import HandleInput\nfrom langflow.io import DropdownInput, IntInput, MessageTextInput, MultilineInput, Output\nfrom langflow.memory import LCBuiltinChatMemory, get_messages\nfrom langflow.schema import Data\nfrom langflow.schema.message import Message\nfrom langflow.utils.constants import MESSAGE_SENDER_AI, MESSAGE_SENDER_USER\n\n\nclass MemoryComponent(Component):\n display_name = \"Chat Memory\"\n description = \"Retrieves stored chat messages from Langflow tables or an external memory.\"\n icon = \"message-square-more\"\n name = \"Memory\"\n\n inputs = [\n HandleInput(\n name=\"memory\",\n display_name=\"External Memory\",\n input_types=[\"BaseChatMessageHistory\"],\n info=\"Retrieve messages from an external memory. If empty, it will use the Langflow tables.\",\n ),\n DropdownInput(\n name=\"sender\",\n display_name=\"Sender Type\",\n options=[MESSAGE_SENDER_AI, MESSAGE_SENDER_USER, \"Machine and User\"],\n value=\"Machine and User\",\n info=\"Filter by sender type.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"sender_name\",\n display_name=\"Sender Name\",\n info=\"Filter by sender name.\",\n advanced=True,\n ),\n IntInput(\n name=\"n_messages\",\n display_name=\"Number of Messages\",\n value=100,\n info=\"Number of messages to retrieve.\",\n advanced=True,\n ),\n MessageTextInput(\n name=\"session_id\",\n display_name=\"Session ID\",\n info=\"The session ID of the chat. If empty, the current session ID parameter will be used.\",\n advanced=True,\n ),\n DropdownInput(\n name=\"order\",\n display_name=\"Order\",\n options=[\"Ascending\", \"Descending\"],\n value=\"Ascending\",\n info=\"Order of the messages.\",\n advanced=True,\n ),\n MultilineInput(\n name=\"template\",\n display_name=\"Template\",\n info=\"The template to use for formatting the data. \"\n \"It can contain the keys {text}, {sender} or any other key in the message data.\",\n value=\"{sender_name}: {text}\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"Data\", name=\"messages\", method=\"retrieve_messages\"),\n Output(display_name=\"Text\", name=\"messages_text\", method=\"retrieve_messages_as_text\"),\n ]\n\n def retrieve_messages(self) -> Data:\n sender = self.sender\n sender_name = self.sender_name\n session_id = self.session_id\n n_messages = self.n_messages\n order = \"DESC\" if self.order == \"Descending\" else \"ASC\"\n\n if sender == \"Machine and User\":\n sender = None\n\n if self.memory:\n # override session_id\n self.memory.session_id = session_id\n\n stored = self.memory.messages\n # langchain memories are supposed to return messages in ascending order\n if order == \"DESC\":\n stored = stored[::-1]\n if n_messages:\n stored = stored[:n_messages]\n stored = [Message.from_lc_message(m) for m in stored]\n if sender:\n expected_type = MESSAGE_SENDER_AI if sender == MESSAGE_SENDER_AI else MESSAGE_SENDER_USER\n stored = [m for m in stored if m.type == expected_type]\n else:\n stored = get_messages(\n sender=sender,\n sender_name=sender_name,\n session_id=session_id,\n limit=n_messages,\n order=order,\n )\n self.status = stored\n return stored\n\n def retrieve_messages_as_text(self) -> Message:\n stored_text = data_to_text(self.template, self.retrieve_messages())\n self.status = stored_text\n return Message(text=stored_text)\n\n def build_lc_memory(self) -> BaseChatMemory:\n chat_memory = self.memory or LCBuiltinChatMemory(flow_id=self.flow_id, session_id=self.session_id)\n return ConversationBufferMemory(chat_memory=chat_memory)\n" }, "memory": { "advanced": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json index 471b6a0ef..23194ff07 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Travel Planning Agents.json @@ -1630,7 +1630,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] | None = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" + "value": "from typing import Any\n\nfrom langchain.tools import StructuredTool\nfrom langchain_community.utilities.searchapi import SearchApiAPIWrapper\nfrom pydantic import BaseModel, Field\n\nfrom langflow.base.langchain_utilities.model import LCToolComponent\nfrom langflow.field_typing import Tool\nfrom langflow.inputs import DictInput, IntInput, MessageTextInput, MultilineInput, SecretStrInput\nfrom langflow.schema import Data\n\n\nclass SearchAPIComponent(LCToolComponent):\n display_name: str = \"Search API\"\n description: str = \"Call the searchapi.io API with result limiting\"\n name = \"SearchAPI\"\n documentation: str = \"https://www.searchapi.io/docs/google\"\n\n inputs = [\n MessageTextInput(name=\"engine\", display_name=\"Engine\", value=\"google\"),\n SecretStrInput(name=\"api_key\", display_name=\"SearchAPI API Key\", required=True),\n MultilineInput(\n name=\"input_value\",\n display_name=\"Input\",\n ),\n DictInput(name=\"search_params\", display_name=\"Search parameters\", advanced=True, is_list=True),\n IntInput(name=\"max_results\", display_name=\"Max Results\", value=5, advanced=True),\n IntInput(name=\"max_snippet_length\", display_name=\"Max Snippet Length\", value=100, advanced=True),\n ]\n\n class SearchAPISchema(BaseModel):\n query: str = Field(..., description=\"The search query\")\n params: dict[str, Any] = Field(default_factory=dict, description=\"Additional search parameters\")\n max_results: int = Field(5, description=\"Maximum number of results to return\")\n max_snippet_length: int = Field(100, description=\"Maximum length of each result snippet\")\n\n def _build_wrapper(self):\n return SearchApiAPIWrapper(engine=self.engine, searchapi_api_key=self.api_key)\n\n def build_tool(self) -> Tool:\n wrapper = self._build_wrapper()\n\n def search_func(\n query: str, params: dict[str, Any] | None = None, max_results: int = 5, max_snippet_length: int = 100\n ) -> list[dict[str, Any]]:\n params = params or {}\n full_results = wrapper.results(query=query, **params)\n organic_results = full_results.get(\"organic_results\", [])[:max_results]\n\n limited_results = []\n for result in organic_results:\n limited_result = {\n \"title\": result.get(\"title\", \"\")[:max_snippet_length],\n \"link\": result.get(\"link\", \"\"),\n \"snippet\": result.get(\"snippet\", \"\")[:max_snippet_length],\n }\n limited_results.append(limited_result)\n\n return limited_results\n\n tool = StructuredTool.from_function(\n name=\"search_api\",\n description=\"Search for recent results using searchapi.io with result limiting\",\n func=search_func,\n args_schema=self.SearchAPISchema,\n )\n\n self.status = f\"Search API Tool created with engine: {self.engine}\"\n return tool\n\n def run_model(self) -> list[Data]:\n tool = self.build_tool()\n results = tool.run(\n {\n \"query\": self.input_value,\n \"params\": self.search_params or {},\n \"max_results\": self.max_results,\n \"max_snippet_length\": self.max_snippet_length,\n }\n )\n\n data_list = [Data(data=result, text=result.get(\"snippet\", \"\")) for result in results]\n\n self.status = data_list\n return data_list\n" }, "engine": { "_input_type": "MessageTextInput", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json index 349091c3e..77305f037 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Vector Store RAG.json @@ -619,18 +619,6 @@ "Data" ], "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Vector Store", - "method": "cast_vector_store", - "name": "vector_store", - "required_inputs": [], - "selected": "VectorStore", - "types": [ - "VectorStore" - ], - "value": "__UNDEFINED__" } ], "pinned": false, @@ -1788,7 +1776,7 @@ "show": true, "title_case": false, "type": "code", - "value": "from pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom zipfile import ZipFile, is_zipfile\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parallel_load_data, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, IntInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n \"\"\"Handles loading of individual or zipped text files.\n\n Processes multiple valid files within a zip archive if provided.\n\n Attributes:\n display_name: Display name of the component.\n description: Brief component description.\n icon: Icon to represent the component.\n name: Identifier for the component.\n inputs: Inputs required by the component.\n outputs: Output of the component after processing files.\n \"\"\"\n\n display_name = \"File\"\n description = \"Load a file to be used in your project.\"\n icon = \"file-text\"\n name = \"File\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=[*TEXT_FILE_TYPES, \"zip\"],\n info=f\"Supported file types: {', '.join([*TEXT_FILE_TYPES, 'zip'])}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n BoolInput(\n name=\"use_multithreading\",\n display_name=\"Use Multithreading\",\n advanced=True,\n info=\"If true, parallel processing will be enabled for zip files.\",\n ),\n IntInput(\n name=\"concurrency_multithreading\",\n display_name=\"Multithreading Concurrency\",\n advanced=True,\n info=\"The maximum number of workers to use, if concurrency is enabled\",\n value=4,\n ),\n ]\n\n outputs = [Output(display_name=\"Data\", name=\"data\", method=\"load_file\")]\n\n def load_file(self) -> Data:\n \"\"\"Load and parse file(s) from a zip archive.\n\n Raises:\n ValueError: If no file is uploaded or file path is invalid.\n\n Returns:\n Data: Parsed data from file(s).\n \"\"\"\n # Check if the file path is provided\n if not self.path:\n self.log(\"File path is missing.\")\n msg = \"Please upload a file for processing.\"\n\n raise ValueError(msg)\n\n resolved_path = Path(self.resolve_path(self.path))\n try:\n # Check if the file is a zip archive\n if is_zipfile(resolved_path):\n self.log(f\"Processing zip file: {resolved_path.name}.\")\n return self._process_zip_file(\n resolved_path,\n silent_errors=self.silent_errors,\n parallel=self.use_multithreading,\n )\n\n self.log(f\"Processing single file: {resolved_path.name}.\")\n return self._process_single_file(resolved_path, silent_errors=self.silent_errors)\n except FileNotFoundError:\n self.log(f\"File not found: {resolved_path.name}.\")\n raise\n\n def _process_zip_file(self, zip_path: Path, *, silent_errors: bool = False, parallel: bool = False) -> Data:\n \"\"\"Process text files within a zip archive.\n\n Args:\n zip_path: Path to the zip file.\n silent_errors: Suppresses errors if True.\n parallel: Enables parallel processing if True.\n\n Returns:\n list[Data]: Combined data from all valid files.\n\n Raises:\n ValueError: If no valid files found in the archive.\n \"\"\"\n data: list[Data] = []\n with ZipFile(zip_path, \"r\") as zip_file:\n # Filter file names based on extensions in TEXT_FILE_TYPES and ignore hidden files\n valid_files = [\n name\n for name in zip_file.namelist()\n if (\n any(name.endswith(ext) for ext in TEXT_FILE_TYPES)\n and not name.startswith(\"__MACOSX\")\n and not name.startswith(\".\")\n )\n ]\n\n # Raise an error if no valid files found\n if not valid_files:\n self.log(\"No valid files in the zip archive.\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return data # type: ignore[return-value]\n\n # Raise an error if no valid files found\n msg = \"No valid files in the zip archive.\"\n raise ValueError(msg)\n\n # Define a function to process each file\n def process_file(file_name, silent_errors=silent_errors):\n with NamedTemporaryFile(delete=False) as temp_file:\n temp_path = Path(temp_file.name).with_name(file_name)\n with zip_file.open(file_name) as file_content:\n temp_path.write_bytes(file_content.read())\n try:\n return self._process_single_file(temp_path, silent_errors=silent_errors)\n finally:\n temp_path.unlink()\n\n # Process files in parallel if specified\n if parallel:\n self.log(\n f\"Initializing parallel Thread Pool Executor with max workers: \"\n f\"{self.concurrency_multithreading}.\"\n )\n\n # Process files in parallel\n initial_data = parallel_load_data(\n valid_files,\n silent_errors=silent_errors,\n load_function=process_file,\n max_concurrency=self.concurrency_multithreading,\n )\n\n # Filter out empty data\n data = list(filter(None, initial_data))\n else:\n # Sequential processing\n data = [process_file(file_name) for file_name in valid_files]\n\n self.log(f\"Successfully processed zip file: {zip_path.name}.\")\n\n return data # type: ignore[return-value]\n\n def _process_single_file(self, file_path: Path, *, silent_errors: bool = False) -> Data:\n \"\"\"Process a single file.\n\n Args:\n file_path: Path to the file.\n silent_errors: Suppresses errors if True.\n\n Returns:\n Data: Parsed data from the file.\n\n Raises:\n ValueError: For unsupported file formats.\n \"\"\"\n # Check if the file type is supported\n if not any(file_path.suffix == ext for ext in [\".\" + f for f in TEXT_FILE_TYPES]):\n self.log(f\"Unsupported file type: {file_path.suffix}\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return Data()\n\n msg = f\"Unsupported file type: {file_path.suffix}\"\n raise ValueError(msg)\n\n try:\n # Parse the text file as appropriate\n data = parse_text_file_to_data(str(file_path), silent_errors=silent_errors) # type: ignore[assignment]\n if not data:\n data = Data()\n\n self.log(f\"Successfully processed file: {file_path.name}.\")\n except Exception as e:\n self.log(f\"Error processing file {file_path.name}: {e}\")\n\n # Return empty data if silent_errors is True\n if not silent_errors:\n raise\n\n data = Data()\n\n return data\n" + "value": "from pathlib import Path\nfrom tempfile import NamedTemporaryFile\nfrom zipfile import ZipFile, is_zipfile\n\nfrom langflow.base.data.utils import TEXT_FILE_TYPES, parallel_load_data, parse_text_file_to_data\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, FileInput, IntInput, Output\nfrom langflow.schema import Data\n\n\nclass FileComponent(Component):\n \"\"\"Handles loading of individual or zipped text files.\n\n Processes multiple valid files within a zip archive if provided.\n\n Attributes:\n display_name: Display name of the component.\n description: Brief component description.\n icon: Icon to represent the component.\n name: Identifier for the component.\n inputs: Inputs required by the component.\n outputs: Output of the component after processing files.\n \"\"\"\n\n display_name = \"File\"\n description = \"Load a file to be used in your project.\"\n icon = \"file-text\"\n name = \"File\"\n\n inputs = [\n FileInput(\n name=\"path\",\n display_name=\"Path\",\n file_types=[*TEXT_FILE_TYPES, \"zip\"],\n info=f\"Supported file types: {', '.join([*TEXT_FILE_TYPES, 'zip'])}\",\n ),\n BoolInput(\n name=\"silent_errors\",\n display_name=\"Silent Errors\",\n advanced=True,\n info=\"If true, errors will not raise an exception.\",\n ),\n BoolInput(\n name=\"use_multithreading\",\n display_name=\"Use Multithreading\",\n advanced=True,\n info=\"If true, parallel processing will be enabled for zip files.\",\n ),\n IntInput(\n name=\"concurrency_multithreading\",\n display_name=\"Multithreading Concurrency\",\n advanced=True,\n info=\"The maximum number of workers to use, if concurrency is enabled\",\n value=4,\n ),\n ]\n\n outputs = [Output(display_name=\"Data\", name=\"data\", method=\"load_file\")]\n\n def load_file(self) -> Data:\n \"\"\"Load and parse file(s) from a zip archive.\n\n Raises:\n ValueError: If no file is uploaded or file path is invalid.\n\n Returns:\n Data: Parsed data from file(s).\n \"\"\"\n # Check if the file path is provided\n if not self.path:\n self.log(\"File path is missing.\")\n msg = \"Please upload a file for processing.\"\n\n raise ValueError(msg)\n\n resolved_path = Path(self.resolve_path(self.path))\n try:\n # Check if the file is a zip archive\n if is_zipfile(resolved_path):\n self.log(f\"Processing zip file: {resolved_path.name}.\")\n\n return self._process_zip_file(\n resolved_path,\n silent_errors=self.silent_errors,\n parallel=self.use_multithreading,\n )\n\n self.log(f\"Processing single file: {resolved_path.name}.\")\n\n return self._process_single_file(resolved_path, silent_errors=self.silent_errors)\n except FileNotFoundError:\n self.log(f\"File not found: {resolved_path.name}.\")\n\n raise\n\n def _process_zip_file(self, zip_path: Path, *, silent_errors: bool = False, parallel: bool = False) -> Data:\n \"\"\"Process text files within a zip archive.\n\n Args:\n zip_path: Path to the zip file.\n silent_errors: Suppresses errors if True.\n parallel: Enables parallel processing if True.\n\n Returns:\n list[Data]: Combined data from all valid files.\n\n Raises:\n ValueError: If no valid files found in the archive.\n \"\"\"\n data: list[Data] = []\n with ZipFile(zip_path, \"r\") as zip_file:\n # Filter file names based on extensions in TEXT_FILE_TYPES and ignore hidden files\n valid_files = [\n name\n for name in zip_file.namelist()\n if (\n any(name.endswith(ext) for ext in TEXT_FILE_TYPES)\n and not name.startswith(\"__MACOSX\")\n and not name.startswith(\".\")\n )\n ]\n\n # Raise an error if no valid files found\n if not valid_files:\n self.log(\"No valid files in the zip archive.\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return data # type: ignore[return-value]\n\n # Raise an error if no valid files found\n msg = \"No valid files in the zip archive.\"\n raise ValueError(msg)\n\n # Define a function to process each file\n def process_file(file_name, silent_errors=silent_errors):\n with NamedTemporaryFile(delete=False) as temp_file:\n temp_path = Path(temp_file.name).with_name(file_name)\n with zip_file.open(file_name) as file_content:\n temp_path.write_bytes(file_content.read())\n try:\n return self._process_single_file(temp_path, silent_errors=silent_errors)\n finally:\n temp_path.unlink()\n\n # Process files in parallel if specified\n if parallel:\n self.log(\n f\"Initializing parallel Thread Pool Executor with max workers: \"\n f\"{self.concurrency_multithreading}.\"\n )\n\n # Process files in parallel\n initial_data = parallel_load_data(\n valid_files,\n silent_errors=silent_errors,\n load_function=process_file,\n max_concurrency=self.concurrency_multithreading,\n )\n\n # Filter out empty data\n data = list(filter(None, initial_data))\n else:\n # Sequential processing\n data = [process_file(file_name) for file_name in valid_files]\n\n self.log(f\"Successfully processed zip file: {zip_path.name}.\")\n\n return data # type: ignore[return-value]\n\n def _process_single_file(self, file_path: Path, *, silent_errors: bool = False) -> Data:\n \"\"\"Process a single file.\n\n Args:\n file_path: Path to the file.\n silent_errors: Suppresses errors if True.\n\n Returns:\n Data: Parsed data from the file.\n\n Raises:\n ValueError: For unsupported file formats.\n \"\"\"\n # Check if the file type is supported\n if not any(file_path.suffix == ext for ext in [\".\" + f for f in TEXT_FILE_TYPES]):\n self.log(f\"Unsupported file type: {file_path.suffix}\")\n\n # Return empty data if silent_errors is True\n if silent_errors:\n return Data()\n\n msg = f\"Unsupported file type: {file_path.suffix}\"\n raise ValueError(msg)\n\n try:\n # Parse the text file as appropriate\n data = parse_text_file_to_data(str(file_path), silent_errors=silent_errors) # type: ignore[assignment]\n if not data:\n data = Data()\n\n self.log(f\"Successfully processed file: {file_path.name}.\")\n except Exception as e:\n self.log(f\"Error processing file {file_path.name}: {e}\")\n\n # Return empty data if silent_errors is True\n if not silent_errors:\n raise\n\n data = Data()\n\n return data\n" }, "concurrency_multithreading": { "_input_type": "IntInput", @@ -1967,18 +1955,6 @@ "Data" ], "value": "__UNDEFINED__" - }, - { - "cache": true, - "display_name": "Vector Store", - "method": "cast_vector_store", - "name": "vector_store", - "required_inputs": [], - "selected": "VectorStore", - "types": [ - "VectorStore" - ], - "value": "__UNDEFINED__" } ], "pinned": false, diff --git a/src/backend/base/langflow/initial_setup/starter_projects/blog_writer.py b/src/backend/base/langflow/initial_setup/starter_projects/blog_writer.py index e8270fd36..5ca700754 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/blog_writer.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/blog_writer.py @@ -1,10 +1,10 @@ from textwrap import dedent from langflow.components.data import URLComponent -from langflow.components.helpers import ParseDataComponent from langflow.components.inputs import TextInputComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput +from langflow.components.processing import ParseDataComponent from langflow.components.prompts import PromptComponent from langflow.graph import Graph diff --git a/src/backend/base/langflow/initial_setup/starter_projects/complex_agent.py b/src/backend/base/langflow/initial_setup/starter_projects/complex_agent.py index c70e9ffac..73dee2caf 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/complex_agent.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/complex_agent.py @@ -1,5 +1,6 @@ -from langflow.components.agents import CrewAIAgentComponent, HierarchicalCrewComponent -from langflow.components.helpers import HierarchicalTaskComponent +from langflow.components.crewai.crewai import CrewAIAgentComponent +from langflow.components.crewai.hierarchical_crew import HierarchicalCrewComponent +from langflow.components.crewai.hierarchical_task import HierarchicalTaskComponent from langflow.components.inputs import ChatInput from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput diff --git a/src/backend/base/langflow/initial_setup/starter_projects/document_qa.py b/src/backend/base/langflow/initial_setup/starter_projects/document_qa.py index 4bb1f764f..562c94e90 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/document_qa.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/document_qa.py @@ -1,8 +1,8 @@ from langflow.components.data import FileComponent -from langflow.components.helpers import ParseDataComponent from langflow.components.inputs import ChatInput from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput +from langflow.components.processing import ParseDataComponent from langflow.components.prompts import PromptComponent from langflow.graph import Graph diff --git a/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py b/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py index ce3476b04..5ecff69c3 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/hierarchical_tasks_agent.py @@ -1,5 +1,6 @@ -from langflow.components.agents import CrewAIAgentComponent, HierarchicalCrewComponent -from langflow.components.helpers import HierarchicalTaskComponent +from langflow.components.crewai.crewai import CrewAIAgentComponent +from langflow.components.crewai.hierarchical_crew import HierarchicalCrewComponent +from langflow.components.crewai.hierarchical_task import HierarchicalTaskComponent from langflow.components.inputs import ChatInput from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput diff --git a/src/backend/base/langflow/initial_setup/starter_projects/memory_chatbot.py b/src/backend/base/langflow/initial_setup/starter_projects/memory_chatbot.py index 7bf74b126..ffc419463 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/memory_chatbot.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/memory_chatbot.py @@ -1,5 +1,5 @@ -from langflow.components.helpers import MemoryComponent from langflow.components.inputs import ChatInput +from langflow.components.memories import MemoryComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput from langflow.components.prompts import PromptComponent diff --git a/src/backend/base/langflow/initial_setup/starter_projects/sequential_tasks_agent.py b/src/backend/base/langflow/initial_setup/starter_projects/sequential_tasks_agent.py index 5b011e866..5b0664f9e 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/sequential_tasks_agent.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/sequential_tasks_agent.py @@ -1,4 +1,5 @@ -from langflow.components.agents import SequentialCrewComponent, SequentialTaskAgentComponent +from langflow.components.crewai.sequential_crew import SequentialCrewComponent +from langflow.components.crewai.sequential_task_agent import SequentialTaskAgentComponent from langflow.components.inputs import TextInputComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput diff --git a/src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.py b/src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.py index b8ba8aeba..4675249f0 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.py +++ b/src/backend/base/langflow/initial_setup/starter_projects/vector_store_rag.py @@ -2,10 +2,11 @@ from textwrap import dedent from langflow.components.data import FileComponent from langflow.components.embeddings import OpenAIEmbeddingsComponent -from langflow.components.helpers import ParseDataComponent, SplitTextComponent +from langflow.components.helpers import SplitTextComponent from langflow.components.inputs import ChatInput from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput +from langflow.components.processing import ParseDataComponent from langflow.components.prompts import PromptComponent from langflow.components.vectorstores import AstraVectorStoreComponent from langflow.graph import Graph diff --git a/src/backend/tests/integration/components/helpers/test_parse_json_data.py b/src/backend/tests/integration/components/helpers/test_parse_json_data.py index d0aff47ca..aed3311da 100644 --- a/src/backend/tests/integration/components/helpers/test_parse_json_data.py +++ b/src/backend/tests/integration/components/helpers/test_parse_json_data.py @@ -1,5 +1,5 @@ -from langflow.components.helpers import ParseJSONDataComponent from langflow.components.inputs import ChatInput +from langflow.components.processing.parse_json_data import ParseJSONDataComponent from langflow.schema import Data from tests.integration.components.mock_components import TextToData diff --git a/src/backend/tests/integration/components/output_parsers/test_output_parser.py b/src/backend/tests/integration/components/output_parsers/test_output_parser.py index 619acb94a..57322a7da 100644 --- a/src/backend/tests/integration/components/output_parsers/test_output_parser.py +++ b/src/backend/tests/integration/components/output_parsers/test_output_parser.py @@ -1,8 +1,8 @@ import os import pytest +from langflow.components.helpers import OutputParserComponent from langflow.components.models import OpenAIModelComponent -from langflow.components.output_parsers import OutputParserComponent from langflow.components.prompts import PromptComponent from tests.integration.utils import ComponentInputHandle, run_single_component diff --git a/src/backend/tests/unit/base/tools/test_component_toolkit.py b/src/backend/tests/unit/base/tools/test_component_toolkit.py index 4a12da75b..fd05f3a4a 100644 --- a/src/backend/tests/unit/base/tools/test_component_toolkit.py +++ b/src/backend/tests/unit/base/tools/test_component_toolkit.py @@ -2,7 +2,7 @@ import os import pytest from langflow.base.tools.component_tool import ComponentToolkit -from langflow.components.agents import ToolCallingAgentComponent +from langflow.components.langchain_utilities import ToolCallingAgentComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput from langflow.components.tools.calculator import CalculatorToolComponent diff --git a/src/backend/tests/unit/components/agents/test_tool_calling_agent.py b/src/backend/tests/unit/components/agents/test_tool_calling_agent.py index a51321429..5affc0e57 100644 --- a/src/backend/tests/unit/components/agents/test_tool_calling_agent.py +++ b/src/backend/tests/unit/components/agents/test_tool_calling_agent.py @@ -1,7 +1,7 @@ import os import pytest -from langflow.components.agents.tool_calling import ToolCallingAgentComponent +from langflow.components.langchain_utilities import ToolCallingAgentComponent from langflow.components.models.openai import OpenAIModelComponent from langflow.components.tools.calculator import CalculatorToolComponent diff --git a/src/backend/tests/unit/components/models/test_huggingface.py b/src/backend/tests/unit/components/models/test_huggingface.py index 6bd313e4f..b813c5b47 100644 --- a/src/backend/tests/unit/components/models/test_huggingface.py +++ b/src/backend/tests/unit/components/models/test_huggingface.py @@ -1,7 +1,6 @@ +from langflow.components.models.huggingface import HuggingFaceEndpointsComponent from langflow.inputs.inputs import DictInput, DropdownInput, FloatInput, HandleInput, IntInput, SecretStrInput, StrInput -from src.backend.base.langflow.components.models.huggingface import HuggingFaceEndpointsComponent - def test_huggingface_inputs(): component = HuggingFaceEndpointsComponent() diff --git a/src/backend/tests/unit/components/prototypes/test_create_data_component.py b/src/backend/tests/unit/components/prototypes/test_create_data_component.py index a5c9c2aa5..22fb8a23d 100644 --- a/src/backend/tests/unit/components/prototypes/test_create_data_component.py +++ b/src/backend/tests/unit/components/prototypes/test_create_data_component.py @@ -1,5 +1,5 @@ import pytest -from langflow.components.prototypes import CreateDataComponent +from langflow.components.processing import CreateDataComponent from langflow.schema import Data diff --git a/src/backend/tests/unit/components/prototypes/test_update_data_component.py b/src/backend/tests/unit/components/prototypes/test_update_data_component.py index 88a65aee0..747b37569 100644 --- a/src/backend/tests/unit/components/prototypes/test_update_data_component.py +++ b/src/backend/tests/unit/components/prototypes/test_update_data_component.py @@ -1,5 +1,5 @@ import pytest -from langflow.components.prototypes import UpdateDataComponent +from langflow.components.processing import UpdateDataComponent from langflow.schema import Data diff --git a/src/backend/tests/unit/custom/custom_component/test_component.py b/src/backend/tests/unit/custom/custom_component/test_component.py index ed2e426ab..400eb06b1 100644 --- a/src/backend/tests/unit/custom/custom_component/test_component.py +++ b/src/backend/tests/unit/custom/custom_component/test_component.py @@ -1,7 +1,7 @@ import pytest -from langflow.components.agents import CrewAIAgentComponent, ToolCallingAgentComponent -from langflow.components.helpers import SequentialTaskComponent +from langflow.components.crewai import CrewAIAgentComponent, SequentialTaskComponent from langflow.components.inputs import ChatInput +from langflow.components.langchain_utilities import ToolCallingAgentComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput from langflow.template import Output diff --git a/src/backend/tests/unit/graph/graph/test_base.py b/src/backend/tests/unit/graph/graph/test_base.py index 4e56e4211..75b9aa9fe 100644 --- a/src/backend/tests/unit/graph/graph/test_base.py +++ b/src/backend/tests/unit/graph/graph/test_base.py @@ -3,8 +3,8 @@ import logging from collections import deque import pytest -from langflow.components.agents import ToolCallingAgentComponent from langflow.components.inputs import ChatInput +from langflow.components.langchain_utilities import ToolCallingAgentComponent from langflow.components.outputs import ChatOutput, TextOutputComponent from langflow.components.tools import YfinanceToolComponent from langflow.graph import Graph diff --git a/src/backend/tests/unit/graph/graph/test_cycles.py b/src/backend/tests/unit/graph/graph/test_cycles.py index 467aa5096..0179e9ba5 100644 --- a/src/backend/tests/unit/graph/graph/test_cycles.py +++ b/src/backend/tests/unit/graph/graph/test_cycles.py @@ -3,10 +3,10 @@ import os import pytest from langflow.components.inputs import ChatInput from langflow.components.inputs.text import TextInputComponent +from langflow.components.logic.conditional_router import ConditionalRouterComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput, TextOutputComponent from langflow.components.prompts import PromptComponent -from langflow.components.prototypes import ConditionalRouterComponent from langflow.custom import Component from langflow.graph import Graph from langflow.graph.graph.utils import find_cycle_vertices diff --git a/src/backend/tests/unit/graph/graph/test_graph_state_model.py b/src/backend/tests/unit/graph/graph/test_graph_state_model.py index 0fbe00adc..036e13a29 100644 --- a/src/backend/tests/unit/graph/graph/test_graph_state_model.py +++ b/src/backend/tests/unit/graph/graph/test_graph_state_model.py @@ -1,8 +1,8 @@ from typing import TYPE_CHECKING import pytest -from langflow.components.helpers import MemoryComponent from langflow.components.inputs import ChatInput +from langflow.components.memories import MemoryComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput from langflow.components.prompts import PromptComponent diff --git a/src/backend/tests/unit/initial_setup/starter_projects/test_memory_chatbot.py b/src/backend/tests/unit/initial_setup/starter_projects/test_memory_chatbot.py index 024433335..f47ffea02 100644 --- a/src/backend/tests/unit/initial_setup/starter_projects/test_memory_chatbot.py +++ b/src/backend/tests/unit/initial_setup/starter_projects/test_memory_chatbot.py @@ -3,8 +3,8 @@ from collections import deque from typing import TYPE_CHECKING import pytest -from langflow.components.helpers import MemoryComponent from langflow.components.inputs import ChatInput +from langflow.components.memories import MemoryComponent from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput from langflow.components.prompts import PromptComponent diff --git a/src/backend/tests/unit/initial_setup/starter_projects/test_vector_store_rag.py b/src/backend/tests/unit/initial_setup/starter_projects/test_vector_store_rag.py index 36e462c10..ad31376f3 100644 --- a/src/backend/tests/unit/initial_setup/starter_projects/test_vector_store_rag.py +++ b/src/backend/tests/unit/initial_setup/starter_projects/test_vector_store_rag.py @@ -5,10 +5,11 @@ from textwrap import dedent import pytest from langflow.components.data import FileComponent from langflow.components.embeddings import OpenAIEmbeddingsComponent -from langflow.components.helpers import ParseDataComponent, SplitTextComponent +from langflow.components.helpers import SplitTextComponent from langflow.components.inputs import ChatInput from langflow.components.models import OpenAIModelComponent from langflow.components.outputs import ChatOutput +from langflow.components.processing import ParseDataComponent from langflow.components.prompts import PromptComponent from langflow.components.vectorstores import AstraVectorStoreComponent from langflow.graph import Graph @@ -35,7 +36,6 @@ def ingestion_graph(): api_endpoint="https://astra.example.com", token="token", # noqa: S106 ) - vector_store.set_on_output(name="vector_store", value="mock_vector_store", cache=True) vector_store.set_on_output(name="base_retriever", value="mock_retriever", cache=True) vector_store.set_on_output(name="search_results", value=[Data(text="This is a test file.")], cache=True) @@ -64,7 +64,6 @@ def rag_graph(): ], cache=True, ) - rag_vector_store.set_on_output(name="vector_store", value="mock_vector_store", cache=True) rag_vector_store.set_on_output(name="base_retriever", value="mock_retriever", cache=True) parse_data = ParseDataComponent(_id="parse-data-123") parse_data.set(data=rag_vector_store.search_documents) diff --git a/src/backend/tests/unit/test_helper_components.py b/src/backend/tests/unit/test_helper_components.py index 9326bedc4..6469e6026 100644 --- a/src/backend/tests/unit/test_helper_components.py +++ b/src/backend/tests/unit/test_helper_components.py @@ -1,6 +1,6 @@ from pathlib import Path -from langflow.components import helpers +from langflow.components import helpers, processing from langflow.custom.utils import build_custom_component_template from langflow.schema import Data from langflow.schema.message import Message @@ -53,7 +53,7 @@ def test_uuid_generator_component(): def test_data_as_text_component(): # Arrange - data_as_text_component = helpers.ParseDataComponent() + data_as_text_component = processing.ParseDataComponent() # Act # Replace with your actual test data diff --git a/src/frontend/package-lock.json b/src/frontend/package-lock.json index 6bd431769..dd64d3d24 100644 --- a/src/frontend/package-lock.json +++ b/src/frontend/package-lock.json @@ -835,7 +835,6 @@ }, "node_modules/@clack/prompts/node_modules/is-unicode-supported": { "version": "1.3.0", - "extraneous": true, "inBundle": true, "license": "MIT", "engines": { @@ -1641,9 +1640,9 @@ } }, "node_modules/@humanwhocodes/retry": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.0.tgz", - "integrity": "sha512-xnRgu9DxZbkWak/te3fcytNyp8MTbuiZIaueg2rgEvBuN55n04nwLYLU9TX/VVlusc9L2ZNXi99nUFNkHXtr5g==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.1.tgz", + "integrity": "sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==", "dev": true, "engines": { "node": ">=18.18" @@ -2315,7 +2314,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-3.0.0.tgz", "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==", - "license": "MIT", "engines": { "node": ">=12" }, @@ -2327,7 +2325,6 @@ "version": "8.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-8.0.0.tgz", "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", - "license": "MIT", "dependencies": { "parse-ms": "^3.0.0" }, @@ -4103,9 +4100,9 @@ } }, "node_modules/@remix-run/router": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.20.0.tgz", - "integrity": "sha512-mUnk8rPJBI9loFDZ+YzPGdeniYK+FTmRD1TMCz7ev2SNIozyKKpnGgsxO34u6Z4z/t0ITuu7voi/AshfsGsgFg==", + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz", + "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==", "engines": { "node": ">=14.0.0" } @@ -4659,9 +4656,9 @@ } }, "node_modules/@swc/core": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.8.0.tgz", - "integrity": "sha512-EF8C5lp1RKMp3426tAKwQyVbg4Zcn/2FDax3cz8EcOXYQJM/ctB687IvBm9Ciej1wMcQ/dMRg+OB4Xl8BGLBoA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.9.1.tgz", + "integrity": "sha512-OnPc+Kt5oy3xTvr/KCUOqE9ptJcWbyQgAUr1ydh9EmbBcmJTaO1kfQCxm/axzJi6sKeDTxL9rX5zvLOhoYIaQw==", "dev": true, "hasInstallScript": true, "dependencies": { @@ -4676,16 +4673,16 @@ "url": "https://opencollective.com/swc" }, "optionalDependencies": { - "@swc/core-darwin-arm64": "1.8.0", - "@swc/core-darwin-x64": "1.8.0", - "@swc/core-linux-arm-gnueabihf": "1.8.0", - "@swc/core-linux-arm64-gnu": "1.8.0", - "@swc/core-linux-arm64-musl": "1.8.0", - "@swc/core-linux-x64-gnu": "1.8.0", - "@swc/core-linux-x64-musl": "1.8.0", - "@swc/core-win32-arm64-msvc": "1.8.0", - "@swc/core-win32-ia32-msvc": "1.8.0", - "@swc/core-win32-x64-msvc": "1.8.0" + "@swc/core-darwin-arm64": "1.9.1", + "@swc/core-darwin-x64": "1.9.1", + "@swc/core-linux-arm-gnueabihf": "1.9.1", + "@swc/core-linux-arm64-gnu": "1.9.1", + "@swc/core-linux-arm64-musl": "1.9.1", + "@swc/core-linux-x64-gnu": "1.9.1", + "@swc/core-linux-x64-musl": "1.9.1", + "@swc/core-win32-arm64-msvc": "1.9.1", + "@swc/core-win32-ia32-msvc": "1.9.1", + "@swc/core-win32-x64-msvc": "1.9.1" }, "peerDependencies": { "@swc/helpers": "*" @@ -4697,9 +4694,9 @@ } }, "node_modules/@swc/core-darwin-arm64": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.8.0.tgz", - "integrity": "sha512-TIus1/SE/Ud4g84hCnchcagu+LfyndSDy5r5qf64nflojejDidPU9Fp1InzQhQpEgIpntnZID/KFCP5rQnvsIw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.9.1.tgz", + "integrity": "sha512-2/ncHSCdAh5OHem1fMITrWEzzl97OdMK1PHc9CkxSJnphLjRubfxB5sbc5tDhcO68a5tVy+DxwaBgDec3PXnOg==", "cpu": [ "arm64" ], @@ -4713,9 +4710,9 @@ } }, "node_modules/@swc/core-darwin-x64": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.8.0.tgz", - "integrity": "sha512-yCb1FHCX/HUmNRGB1X3CFJ1WPKXMosZVUe3K2TrosCGvytwgaLoW5FS0bZg5Qv6cEUERQBg75cJnOUPwLLRCVg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.9.1.tgz", + "integrity": "sha512-4MDOFC5zmNqRJ9RGFOH95oYf27J9HniLVpB1pYm2gGeNHdl2QvDMtx2QTuMHQ6+OTn/3y1BHYuhBGp7d405oLA==", "cpu": [ "x64" ], @@ -4729,9 +4726,9 @@ } }, "node_modules/@swc/core-linux-arm-gnueabihf": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.8.0.tgz", - "integrity": "sha512-6TdjVdiLaSW+eGiHKEojMDlx673nowrPHa6nM6toWgRzy8tIZgjPOguVKJDoMnoHuvO7SkOLCUiMRw0rTskypA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.9.1.tgz", + "integrity": "sha512-eVW/BjRW8/HpLe3+1jRU7w7PdRLBgnEEYTkHJISU8805/EKT03xNZn6CfaBpKfeAloY4043hbGzE/NP9IahdpQ==", "cpu": [ "arm" ], @@ -4745,9 +4742,9 @@ } }, "node_modules/@swc/core-linux-arm64-gnu": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.8.0.tgz", - "integrity": "sha512-TU2YcTornnyZiJUabRuk7Xtvzaep11FwK77IkFomjN9/Os5s25B8ea652c2fAQMe9RsM84FPVmX303ohxavjKQ==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.9.1.tgz", + "integrity": "sha512-8m3u1v8R8NgI/9+cHMkzk14w87blSy3OsQPWPfhOL+XPwhyLPvat+ahQJb2nZmltjTgkB4IbzKFSfbuA34LmNA==", "cpu": [ "arm64" ], @@ -4761,9 +4758,9 @@ } }, "node_modules/@swc/core-linux-arm64-musl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.8.0.tgz", - "integrity": "sha512-2CdPTEKxx2hJIj/B0fn8L8k2coo/FDS95smzXyi2bov5FcrP6Ohboq8roFBYgj38fkHusXjY8qt+cCH7yXWAdg==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.9.1.tgz", + "integrity": "sha512-hpT0sQAZnW8l02I289yeyFfT9llGO9PzKDxUq8pocKtioEHiElRqR53juCWoSmzuWi+6KX7zUJ0NKCBrc8pmDg==", "cpu": [ "arm64" ], @@ -4777,9 +4774,9 @@ } }, "node_modules/@swc/core-linux-x64-gnu": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.8.0.tgz", - "integrity": "sha512-14StQBifCs/AMsySdU95OmwNJr9LOVqo6rcTFt2b7XaWpe/AyeuMJFxcndLgUewksJHpfepzCTwNdbcYmuNo6A==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.9.1.tgz", + "integrity": "sha512-sGFdpdAYusk/ropHiwtXom2JrdaKPxl8MqemRv6dvxZq1Gm/GdmOowxdXIPjCgBGMgoXVcgNviH6CgiO5q+UtA==", "cpu": [ "x64" ], @@ -4793,9 +4790,9 @@ } }, "node_modules/@swc/core-linux-x64-musl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.8.0.tgz", - "integrity": "sha512-qemJnAQlYqKCfWNqVv5SG8uGvw8JotwU86cuFUkq35oTB+dsSFM3b83+B1giGTKKFOh2nfWT7bvPXTKk+aUjew==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.9.1.tgz", + "integrity": "sha512-YtNLNwIWs0Z2+XgBs6+LrCIGtfCDtNr4S4b6Q5HDOreEIGzSvhkef8eyBI5L+fJ2eGov4b7iEo61C4izDJS5RA==", "cpu": [ "x64" ], @@ -4809,9 +4806,9 @@ } }, "node_modules/@swc/core-win32-arm64-msvc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.8.0.tgz", - "integrity": "sha512-fXt5vZbnrVdXZzGj2qRnZtY3uh+NtLCaFjS2uD9w8ssdbjhbDZYlJCj2JINOjv35ttEfAD2goiYmVa5P/Ypl+g==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.9.1.tgz", + "integrity": "sha512-qSxD3uZW2vSiHqUt30vUi0PB92zDh9bjqh5YKpfhhVa7h1vt/xXhlid8yMvSNToTfzhRrTEffOAPUr7WVoyQUA==", "cpu": [ "arm64" ], @@ -4825,9 +4822,9 @@ } }, "node_modules/@swc/core-win32-ia32-msvc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.8.0.tgz", - "integrity": "sha512-W4FA2vSJ+bGYiTj6gspxghSdKQNLfLMo65AH07u797x7I+YJj8amnFY/fQRlroDv5Dez/FHTv14oPlTlNFUpIw==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.9.1.tgz", + "integrity": "sha512-C3fPEwyX/WRPlX6zIToNykJuz1JkZX0sk8H1QH2vpnKuySUkt/Ur5K2FzLgSWzJdbfxstpgS151/es0VGAD+ZA==", "cpu": [ "ia32" ], @@ -4841,9 +4838,9 @@ } }, "node_modules/@swc/core-win32-x64-msvc": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.8.0.tgz", - "integrity": "sha512-Il4y8XwKDV0Bnk0IpA00kGcSQC6I9XOIinW5egTutnwIDfDE+qsD0j+0isW5H76GetY3/Ze0lVxeOXLAUgpegA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.9.1.tgz", + "integrity": "sha512-2XZ+U1AyVsOAXeH6WK1syDm7+gwTjA8fShs93WcbxnK7HV+NigDlvr4124CeJLTHyh3fMh1o7+CnQnaBJhlysQ==", "cpu": [ "x64" ], @@ -4950,20 +4947,20 @@ } }, "node_modules/@tanstack/query-core": { - "version": "5.59.17", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.17.tgz", - "integrity": "sha512-jWdDiif8kaqnRGHNXAa9CnudtxY5v9DUxXhodgqX2Rwzj+1UwStDHEbBd9IA5C7VYAaJ2s+BxFR6PUBs8ERorA==", + "version": "5.59.20", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.59.20.tgz", + "integrity": "sha512-e8vw0lf7KwfGe1if4uPFhvZRWULqHjFcz3K8AebtieXvnMOz5FSzlZe3mTLlPuUBcydCnBRqYs2YJ5ys68wwLg==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" } }, "node_modules/@tanstack/react-query": { - "version": "5.59.19", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.19.tgz", - "integrity": "sha512-xLRfyFyQOFcLltKCds0LijfC6/HQJrrTTnZB8ciyn74LIkVAm++vZJ6eUVG20RmJtdP8REdy7vSOYW4M3//XLA==", + "version": "5.59.20", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.59.20.tgz", + "integrity": "sha512-Zly0egsK0tFdfSbh5/mapSa+Zfc3Et0Zkar7Wo5sQkFzWyB3p3uZWOHR2wrlAEEV2L953eLuDBtbgFvMYiLvUw==", "dependencies": { - "@tanstack/query-core": "5.59.17" + "@tanstack/query-core": "5.59.20" }, "funding": { "type": "github", @@ -4974,11 +4971,11 @@ } }, "node_modules/@tanstack/react-virtual": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.8.tgz", - "integrity": "sha512-VbzbVGSsZlQktyLrP5nxE+vE1ZR+U0NFAWPbJLoG2+DKPwd2D7dVICTVIIaYlJqX1ZCEnYDbaOpmMwbsyhBoIA==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.10.9.tgz", + "integrity": "sha512-OXO2uBjFqA4Ibr2O3y0YMnkrRWGVNqcvHQXmGvMu6IK8chZl3PrDxFXdGZ2iZkSrKh3/qUYoFqYe+Rx23RoU0g==", "dependencies": { - "@tanstack/virtual-core": "3.10.8" + "@tanstack/virtual-core": "3.10.9" }, "funding": { "type": "github", @@ -4990,9 +4987,9 @@ } }, "node_modules/@tanstack/virtual-core": { - "version": "3.10.8", - "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.8.tgz", - "integrity": "sha512-PBu00mtt95jbKFi6Llk9aik8bnR3tR/oQP1o3TSi+iG//+Q2RTIzCEgKkHG8BB86kxMNW6O8wku+Lmi+QFR6jA==", + "version": "3.10.9", + "resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.10.9.tgz", + "integrity": "sha512-kBknKOKzmeR7lN+vSadaKWXaLS0SZZG+oqpQ/k80Q6g9REn6zRHS/ZYdrIzHnpHgy/eWs00SujveUN/GJT2qTw==", "funding": { "type": "github", "url": "https://github.com/sponsors/tannerlinsley" @@ -5683,9 +5680,9 @@ "optional": true }, "node_modules/ace-builds": { - "version": "1.36.3", - "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.36.3.tgz", - "integrity": "sha512-YcdwV2IIaJSfjkWAR1NEYN5IxBiXefTgwXsJ//UlaFrjXDX5hQpvPFvEePHz2ZBUfvO54RjHeRUQGX8MS5HaMQ==" + "version": "1.36.4", + "resolved": "https://registry.npmjs.org/ace-builds/-/ace-builds-1.36.4.tgz", + "integrity": "sha512-eE+iAsLRfNsq30yd34cezKSob6/N9mQatWs44Bp5LUDgKZ3rJtQds/YtcbnwbEWMTe7yCIxG/Cfezd4BsKIiFg==" }, "node_modules/acorn": { "version": "8.14.0", @@ -6339,9 +6336,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001677.tgz", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001678", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001678.tgz", + "integrity": "sha512-RR+4U/05gNtps58PEBDZcPWTgEO2MBeoPZ96aQcjmfkBWRIDfN451fW2qyDA9/+HohLLIL5GqiMwA+IB1pWarw==", "funding": [ { "type": "opencollective", @@ -6762,9 +6759,9 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.5.tgz", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -7218,17 +7215,17 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/effect": { - "version": "3.10.9", - "resolved": "https://registry.npmjs.org/effect/-/effect-3.10.9.tgz", - "integrity": "sha512-nNRknWPKCBDvAfsoJ/XsxTvIsN9mRdnM02AD6SMPGmHE3dIpnG1lTC/3ywjSYtU7YtBhFV64s2KKaDzdIU8p4Q==", + "version": "3.10.12", + "resolved": "https://registry.npmjs.org/effect/-/effect-3.10.12.tgz", + "integrity": "sha512-+IqqTQS5+jM13qZHzfAX+RpCGOl0oBWIR7nec/zq76HyN/hdGQYnfr/LLLOVxUt8uIbckBea8rkwBKrQ0Hb/aA==", "dependencies": { "fast-check": "^3.21.0" } }, "node_modules/electron-to-chromium": { - "version": "1.5.50", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.50.tgz", - "integrity": "sha512-eMVObiUQ2LdgeO1F/ySTXsvqvxb6ZH2zPGaMYsWzRDdOddUa77tdmI0ltg+L16UpbWdhPmuF3wIQYyQq65WfZw==" + "version": "1.5.55", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.55.tgz", + "integrity": "sha512-6maZ2ASDOTBtjt9FhqYPRnbvKU5tjG0IN9SztUOWYw2AzNDNpKJYLJmlK0/En4Hs/aiWnB+JZ+gW19PIGszgKg==" }, "node_modules/elkjs": { "version": "0.9.3", @@ -11735,7 +11732,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", - "license": "MIT", "engines": { "node": ">=18" }, @@ -11830,9 +11826,9 @@ } }, "node_modules/path2d": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.1.tgz", - "integrity": "sha512-Fl2z/BHvkTNvkuBzYTpTuirHZg6wW9z8+4SND/3mDTEcYbbNKWAy21dz9D3ePNNwrrK8pqZO5vLPZ1hLF6T7XA==", + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/path2d/-/path2d-0.2.2.tgz", + "integrity": "sha512-+vnG6S4dYcYxZd+CZxzXCNKdELYZSKfohrk98yajCo1PtRoDgCTrrwOvK1GT0UoAdVszagDVllQc0U1vaX4NUQ==", "optional": true, "engines": { "node": ">=6" @@ -12285,7 +12281,6 @@ "version": "9.1.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.1.0.tgz", "integrity": "sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==", - "license": "MIT", "dependencies": { "parse-ms": "^4.0.0" }, @@ -12360,9 +12355,12 @@ "dev": true }, "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.10.0.tgz", + "integrity": "sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==", + "dependencies": { + "punycode": "^2.3.1" + } }, "node_modules/pump": { "version": "3.0.2", @@ -12709,11 +12707,11 @@ } }, "node_modules/react-router": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.27.0.tgz", - "integrity": "sha512-YA+HGZXz4jaAkVoYBE98VQl+nVzI+cVI2Oj/06F5ZM+0u3TgedN9Y9kmMRo2mnkSK2nCpNQn0DVob4HCsY/WLw==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz", + "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==", "dependencies": { - "@remix-run/router": "1.20.0" + "@remix-run/router": "1.21.0" }, "engines": { "node": ">=14.0.0" @@ -12723,12 +12721,12 @@ } }, "node_modules/react-router-dom": { - "version": "6.27.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.27.0.tgz", - "integrity": "sha512-+bvtFWMC0DgAFrfKXKG9Fc+BcXWRUO1aJIihbB79xaeq0v5UzfvnM5houGUm1Y461WVRcgAQ+Clh5rdb1eCx4g==", + "version": "6.28.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz", + "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==", "dependencies": { - "@remix-run/router": "1.20.0", - "react-router": "6.27.0" + "@remix-run/router": "1.21.0", + "react-router": "6.28.0" }, "engines": { "node": ">=14.0.0" diff --git a/src/frontend/src/CustomNodes/GenericNode/components/NodeName/index.tsx b/src/frontend/src/CustomNodes/GenericNode/components/NodeName/index.tsx index 6e81f79b1..b27b50496 100644 --- a/src/frontend/src/CustomNodes/GenericNode/components/NodeName/index.tsx +++ b/src/frontend/src/CustomNodes/GenericNode/components/NodeName/index.tsx @@ -87,6 +87,7 @@ export default function NodeName({ className={cn( "max-w-44 truncate text-[14px]", validationStatus?.data?.duration && "max-w-36", + beta && "max-w-36", validationStatus?.data?.duration && beta && "max-w-20", isOutdated && "max-w-40", !showNode && "max-w-28", diff --git a/src/frontend/src/icons/Exa/Exa.jsx b/src/frontend/src/icons/Exa/Exa.jsx new file mode 100644 index 000000000..2e499ca08 --- /dev/null +++ b/src/frontend/src/icons/Exa/Exa.jsx @@ -0,0 +1,227 @@ +export const SvgExa = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); +export default SvgExa; diff --git a/src/frontend/src/icons/Exa/index.tsx b/src/frontend/src/icons/Exa/index.tsx new file mode 100644 index 000000000..31f3c0888 --- /dev/null +++ b/src/frontend/src/icons/Exa/index.tsx @@ -0,0 +1,8 @@ +import React, { forwardRef } from "react"; +import SvgExa from "./Exa"; + +export const ExaIcon = forwardRef>( + (props, ref) => { + return ; + }, +); diff --git a/src/frontend/src/icons/Langwatch/index.tsx b/src/frontend/src/icons/Langwatch/index.tsx new file mode 100644 index 000000000..211d22d86 --- /dev/null +++ b/src/frontend/src/icons/Langwatch/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgLangwatch from "./langwatch"; + +export const LangwatchIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/icons/Langwatch/langwatch-icon.svg b/src/frontend/src/icons/Langwatch/langwatch-icon.svg new file mode 100644 index 000000000..917ba30bd --- /dev/null +++ b/src/frontend/src/icons/Langwatch/langwatch-icon.svg @@ -0,0 +1,2213 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/frontend/src/icons/Langwatch/langwatch.jsx b/src/frontend/src/icons/Langwatch/langwatch.jsx new file mode 100644 index 000000000..6da280e30 --- /dev/null +++ b/src/frontend/src/icons/Langwatch/langwatch.jsx @@ -0,0 +1,3209 @@ +const SvgLangwatch = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); +export default SvgLangwatch; diff --git a/src/frontend/src/icons/Mem0/SvgMem.jsx b/src/frontend/src/icons/Mem0/SvgMem.jsx index af00b7482..dbac1c6e9 100644 --- a/src/frontend/src/icons/Mem0/SvgMem.jsx +++ b/src/frontend/src/icons/Mem0/SvgMem.jsx @@ -10,7 +10,7 @@ export default function SvgMem0(props) { > diff --git a/src/frontend/src/icons/Mem0/index.tsx b/src/frontend/src/icons/Mem0/index.tsx index 480ba6176..e079172ff 100644 --- a/src/frontend/src/icons/Mem0/index.tsx +++ b/src/frontend/src/icons/Mem0/index.tsx @@ -1,8 +1,10 @@ +import { useDarkStore } from "@/stores/darkStore"; import React, { forwardRef } from "react"; import SvgMem from "./SvgMem"; export const Mem0 = forwardRef>( (props, ref) => { - return ; + const isdark = useDarkStore((state) => state.dark); + return ; }, ); diff --git a/src/frontend/src/icons/Milvus/Milvus.jsx b/src/frontend/src/icons/Milvus/Milvus.jsx new file mode 100644 index 000000000..d93b1d9a8 --- /dev/null +++ b/src/frontend/src/icons/Milvus/Milvus.jsx @@ -0,0 +1,317 @@ +export const SvgMilvus = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); +export default SvgMilvus; diff --git a/src/frontend/src/icons/Milvus/index.tsx b/src/frontend/src/icons/Milvus/index.tsx new file mode 100644 index 000000000..5e12857b3 --- /dev/null +++ b/src/frontend/src/icons/Milvus/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgMilvus from "./Milvus"; + +export const MilvusIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/icons/ZepMemory/ZepMemory.jsx b/src/frontend/src/icons/ZepMemory/ZepMemory.jsx new file mode 100644 index 000000000..517b11c57 --- /dev/null +++ b/src/frontend/src/icons/ZepMemory/ZepMemory.jsx @@ -0,0 +1,407 @@ +const SvgZepMemory = (props) => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); +export default SvgZepMemory; diff --git a/src/frontend/src/icons/ZepMemory/index.tsx b/src/frontend/src/icons/ZepMemory/index.tsx new file mode 100644 index 000000000..15c990aba --- /dev/null +++ b/src/frontend/src/icons/ZepMemory/index.tsx @@ -0,0 +1,9 @@ +import React, { forwardRef } from "react"; +import SvgZepMemory from "./ZepMemory"; + +export const ZepMemoryIcon = forwardRef< + SVGSVGElement, + React.PropsWithChildren<{}> +>((props, ref) => { + return ; +}); diff --git a/src/frontend/src/icons/ZepMemory/zep-memory.svg b/src/frontend/src/icons/ZepMemory/zep-memory.svg new file mode 100644 index 000000000..701071de2 --- /dev/null +++ b/src/frontend/src/icons/ZepMemory/zep-memory.svg @@ -0,0 +1,269 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx index 6afb6813f..32df5a31f 100644 --- a/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx +++ b/src/frontend/src/pages/FlowPage/components/flowSidebarComponent/index.tsx @@ -467,6 +467,7 @@ export function FlowSidebarComponent() { handleKeyDown(e, item.name) } className="flex cursor-pointer items-center gap-2" + data-testid={`disclosure-bundles-${item.display_name.toLocaleLowerCase()}`} > { await page.waitForTimeout(1000); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.getByTestId("zoom_out").click(); diff --git a/src/frontend/tests/core/features/stop-building.spec.ts b/src/frontend/tests/core/features/stop-building.spec.ts index d4c37578e..b537bda21 100644 --- a/src/frontend/tests/core/features/stop-building.spec.ts +++ b/src/frontend/tests/core/features/stop-building.spec.ts @@ -103,7 +103,7 @@ test("user must be able to stop a building", async ({ page }) => { // await page.waitForTimeout(1000); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.getByTestId("zoom_out").click(); diff --git a/src/frontend/tests/core/integrations/Simple Agent.spec.ts b/src/frontend/tests/core/integrations/Simple Agent.spec.ts index c38e426c3..3ea090d10 100644 --- a/src/frontend/tests/core/integrations/Simple Agent.spec.ts +++ b/src/frontend/tests/core/integrations/Simple Agent.spec.ts @@ -3,7 +3,7 @@ import * as dotenv from "dotenv"; import path from "path"; import uaParser from "ua-parser-js"; -test.skip("Simple Agent", async ({ page }) => { +test("Simple Agent", async ({ page }) => { test.skip( !process?.env?.OPENAI_API_KEY, "OPENAI_API_KEY required to run this test", @@ -148,5 +148,5 @@ test.skip("Simple Agent", async ({ page }) => { pythonWords = await page.getByText("print(").count(); - expect(pythonWords).toBe(1); + expect(pythonWords).toBeGreaterThanOrEqual(1); }); diff --git a/src/frontend/tests/core/integrations/decisionFlow.spec.ts b/src/frontend/tests/core/integrations/decisionFlow.spec.ts index cd9adb16d..48ff5f4d0 100644 --- a/src/frontend/tests/core/integrations/decisionFlow.spec.ts +++ b/src/frontend/tests/core/integrations/decisionFlow.spec.ts @@ -191,6 +191,11 @@ test("should create a flow with decision", async ({ page }) => { timeout: 30000, }); await page.getByTestId("blank-flow").click(); + + await page.getByTestId("sidebar-options-trigger").click(); + await page.getByTestId("sidebar-legacy-switch").isVisible({ timeout: 5000 }); + await page.getByTestId("sidebar-legacy-switch").click(); + //---------------------------------- CHAT INPUT await page.getByTestId("sidebar-search-input").click(); await page.getByTestId("sidebar-search-input").fill("chat input"); @@ -234,25 +239,25 @@ test("should create a flow with decision", async ({ page }) => { await page.getByTestId("sidebar-search-input").fill("parse data"); await page.waitForTimeout(500); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); //---------------------------------- PASS await page.getByTestId("sidebar-search-input").click(); await page.getByTestId("sidebar-search-input").fill("pass"); await page.waitForTimeout(500); await page - .getByTestId("prototypesPass") + .getByTestId("logicPass") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.waitForTimeout(500); await page - .getByTestId("prototypesPass") + .getByTestId("logicPass") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.waitForTimeout(500); await page - .getByTestId("prototypesPass") + .getByTestId("logicPass") .dragTo(page.locator('//*[@id="react-flow-id"]')); //---------------------------------- PROMPT await page.getByTestId("sidebar-search-input").click(); @@ -273,7 +278,7 @@ test("should create a flow with decision", async ({ page }) => { await page.getByTestId("sidebar-search-input").fill("conditional router"); await page.waitForTimeout(500); await page - .getByTestId("prototypesConditional Router") + .getByTestId("logicIf-Else") .dragTo(page.locator('//*[@id="react-flow-id"]')); //---------------------------------- CHAT OUTPUT await page.getByTestId("sidebar-search-input").click(); @@ -293,7 +298,7 @@ test("should create a flow with decision", async ({ page }) => { await page.waitForTimeout(500); await moveElementByX(page, "Chat Output", 700, 0); await page.waitForTimeout(500); - await moveElementByX(page, "Conditional Router", 1100, 0); + await moveElementByX(page, "If-Else", 1100, 0); await page.waitForTimeout(500); await page.getByTestId("fit_view").click(); await moveElementByX(page, "OpenAI", 980, 0); @@ -384,7 +389,7 @@ test("should create a flow with decision", async ({ page }) => { .nth(0) .click(); await page - .getByTestId("handle-conditionalrouter-shownode-input text-left") + .getByTestId("handle-conditionalrouter-shownode-text input-left") .nth(0) .click(); await page.getByTestId("popover-anchor-input-match_text").fill("TRUE"); @@ -405,7 +410,7 @@ test("should create a flow with decision", async ({ page }) => { await page.getByTestId("showignored_message").last().click(); await page.getByText("Close").last().click(); await page - .getByTestId("handle-conditionalrouter-shownode-true route-right") + .getByTestId("handle-conditionalrouter-shownode-true-right") .nth(0) .click(); await page @@ -413,7 +418,7 @@ test("should create a flow with decision", async ({ page }) => { .nth(1) .click(); await page - .getByTestId("handle-conditionalrouter-shownode-false route-right") + .getByTestId("handle-conditionalrouter-shownode-false-right") .nth(0) .click(); await page diff --git a/src/frontend/tests/core/integrations/similarity.spec.ts b/src/frontend/tests/core/integrations/similarity.spec.ts index 8f87646fd..8b3ee6363 100644 --- a/src/frontend/tests/core/integrations/similarity.spec.ts +++ b/src/frontend/tests/core/integrations/similarity.spec.ts @@ -133,7 +133,7 @@ test("user must be able to check similarity between embedding texts", async ({ // await page.waitForTimeout(1000); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.getByTestId("zoom_out").click(); @@ -173,7 +173,7 @@ test("user must be able to check similarity between embedding texts", async ({ // await page.waitForTimeout(1000); await page - .getByTestId("helpersFilter Data") + .getByTestId("processingFilter Data") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.getByTestId("zoom_out").click(); @@ -249,7 +249,7 @@ test("user must be able to check similarity between embedding texts", async ({ //connection 1 const openAiEmbeddingOutput_0 = await page .getByTestId("handle-openaiembeddings-shownode-embeddings-right") - .nth(2); + .nth(0); await openAiEmbeddingOutput_0.hover(); await page.mouse.down(); diff --git a/src/frontend/tests/core/regression/generalBugs-shard-5.spec.ts b/src/frontend/tests/core/regression/generalBugs-shard-5.spec.ts index 0c6dca9a9..54082e65a 100644 --- a/src/frontend/tests/core/regression/generalBugs-shard-5.spec.ts +++ b/src/frontend/tests/core/regression/generalBugs-shard-5.spec.ts @@ -73,7 +73,7 @@ test("should be able to see output preview from grouped components and connect c await page.mouse.up(); await page - .getByTestId("helpersCombine Text") + .getByTestId("processingCombine Text") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page @@ -88,7 +88,7 @@ test("should be able to see output preview from grouped components and connect c await page.mouse.up(); await page - .getByTestId("helpersCombine Text") + .getByTestId("processingCombine Text") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page diff --git a/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts b/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts index 5c09290a3..d79ac493e 100644 --- a/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts +++ b/src/frontend/tests/core/regression/generalBugs-shard-9.spec.ts @@ -41,6 +41,10 @@ test("memory should work as expect", async ({ page }) => { await page.getByTestId("sidebar-search-input").click(); await page.getByTestId("sidebar-search-input").fill("chat memory"); + await page.getByTestId("sidebar-options-trigger").click(); + await page.getByTestId("sidebar-legacy-switch").isVisible({ timeout: 5000 }); + await page.getByTestId("sidebar-legacy-switch").click(); + // Locate the canvas element const canvas = page.locator("#react-flow-id"); // Update the selector if needed @@ -54,8 +58,8 @@ test("memory should work as expect", async ({ page }) => { const startX = canvasBox.x + canvasBox.width / 2; const startY = canvasBox.y + canvasBox.height / 2; - // End point (move 300 pixels to the right) - const endX = startX + 300; + // End point (move 600 pixels to the right) + const endX = startX + 600; const endY = startY; // Hover over the canvas to focus it @@ -72,7 +76,7 @@ test("memory should work as expect", async ({ page }) => { await page.mouse.up(); await page - .getByTestId("helpersChat Memory") + .getByTestId("memoriesChat Memory") .first() .dragTo(page.locator('//*[@id="react-flow-id"]')); @@ -123,9 +127,12 @@ AI: await page.getByText("Edit Prompt", { exact: true }).click(); await page.getByText("Check & Save").last().click(); + await page.getByTestId("fit_view").click(); + await page.getByTestId("fit_view").click(); + //connection 1 const elementChatMemoryOutput = await page - .getByTestId("handle-memory-shownode-messages (text)-right") + .getByTestId("handle-memory-shownode-text-right") .first(); await elementChatMemoryOutput.hover(); await page.mouse.down(); diff --git a/src/frontend/tests/core/unit/codeAreaModalComponent.spec.ts b/src/frontend/tests/core/unit/codeAreaModalComponent.spec.ts index ff7131f85..6d60ccec6 100644 --- a/src/frontend/tests/core/unit/codeAreaModalComponent.spec.ts +++ b/src/frontend/tests/core/unit/codeAreaModalComponent.spec.ts @@ -36,6 +36,10 @@ test("CodeAreaModalComponent", async ({ page }) => { await page.waitForTimeout(1000); + await page.getByTestId("sidebar-options-trigger").click(); + await page.getByTestId("sidebar-legacy-switch").isVisible({ timeout: 5000 }); + await page.getByTestId("sidebar-legacy-switch").click(); + await page .getByTestId("prototypesPython Function") .dragTo(page.locator('//*[@id="react-flow-id"]')); diff --git a/src/frontend/tests/core/unit/fileUploadComponent.spec.ts b/src/frontend/tests/core/unit/fileUploadComponent.spec.ts index 7d6b2af5c..2a756af38 100644 --- a/src/frontend/tests/core/unit/fileUploadComponent.spec.ts +++ b/src/frontend/tests/core/unit/fileUploadComponent.spec.ts @@ -71,7 +71,7 @@ test.skip("should be able to upload a file", async ({ page }) => { await page.getByTestId("sidebar-search-input").click(); await page.getByTestId("sidebar-search-input").fill("parse data"); await page - .getByTestId("helpersParse Data") + .getByTestId("processingParse Data") .first() .dragTo(page.locator('//*[@id="react-flow-id"]')); diff --git a/src/frontend/tests/extended/features/filterEdge-shard-1.spec.ts b/src/frontend/tests/extended/features/filterEdge-shard-1.spec.ts index d47914278..b07aa1dd3 100644 --- a/src/frontend/tests/extended/features/filterEdge-shard-1.spec.ts +++ b/src/frontend/tests/extended/features/filterEdge-shard-1.spec.ts @@ -48,7 +48,7 @@ test("user must see on handle click the possibility connections - RetrievalQA", await page.waitForTimeout(1000); await page - .getByTestId("chainsRetrieval QA") + .getByTestId("langchain_utilitiesRetrieval QA") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -84,11 +84,12 @@ test("user must see on handle click the possibility connections - RetrievalQA", "disclosure-vector stores", "disclosure-embeddings", "disclosure-agents", - "disclosure-chains", "disclosure-memories", - "disclosure-prototypes", - "disclosure-retrievers", - "disclosure-text splitters", + "disclosure-logic", + "disclosure-tools", + "disclosure-bundles-langchain", + "disclosure-bundles-assemblyai", + "disclosure-bundles-datastax", ]; const elementTestIds = [ @@ -96,15 +97,15 @@ test("user must see on handle click the possibility connections - RetrievalQA", "outputsChat Output", "dataAPI Request", "modelsAmazon Bedrock", - "helpersChat Memory", + "memoriesChat Memory", "vectorstoresAstra DB", "embeddingsAmazon Bedrock Embeddings", - "agentsTool Calling Agent", - "chainsConversationChain", + "langchain_utilitiesTool Calling Agent", + "langchain_utilitiesConversationChain", "memoriesAstra DB Chat Memory", - "prototypesConditional Router", - "retrieversSelf Query Retriever", - "textsplittersCharacterTextSplitter", + "logicCondition", + "langchain_utilitiesSelf Query Retriever", + "langchain_utilitiesCharacterTextSplitter", ]; await Promise.all( @@ -179,6 +180,6 @@ test("user must see on handle click the possibility connections - RetrievalQA", await expect(page.getByTestId("disclosure-helpers")).toBeVisible(); await expect(page.getByTestId("disclosure-agents")).toBeVisible(); - await expect(page.getByTestId("disclosure-chains")).toBeVisible(); - await expect(page.getByTestId("disclosure-prototypes")).toBeVisible(); + await expect(page.getByTestId("disclosure-memories")).toBeVisible(); + await expect(page.getByTestId("disclosure-logic")).toBeVisible(); }); diff --git a/src/frontend/tests/extended/regression/generalBugs-shard-11.spec.ts b/src/frontend/tests/extended/regression/generalBugs-shard-11.spec.ts index ce284e6ae..19dcc2685 100644 --- a/src/frontend/tests/extended/regression/generalBugs-shard-11.spec.ts +++ b/src/frontend/tests/extended/regression/generalBugs-shard-11.spec.ts @@ -35,7 +35,7 @@ test("user should be able to use ComposIO without getting api_key error", async await page.waitForTimeout(1000); - const modelElement = await page.getByTestId("toolkitsComposio Tools"); + const modelElement = await page.getByTestId("composioComposio Tools"); const targetElement = await page.locator('//*[@id="react-flow-id"]'); await modelElement.dragTo(targetElement); @@ -102,7 +102,9 @@ test("user should be able to use connect tools", async ({ page }) => { await page.waitForTimeout(1000); - modelElement = await page.getByTestId("agentsTool Calling Agent"); + modelElement = await page.getByTestId( + "langchain_utilitiesTool Calling Agent", + ); targetElement = await page.locator('//*[@id="react-flow-id"]'); await modelElement.dragTo(targetElement); diff --git a/src/frontend/tests/extended/regression/generalBugs-shard-2.spec.ts b/src/frontend/tests/extended/regression/generalBugs-shard-2.spec.ts index fb16c8eee..a4a80ca70 100644 --- a/src/frontend/tests/extended/regression/generalBugs-shard-2.spec.ts +++ b/src/frontend/tests/extended/regression/generalBugs-shard-2.spec.ts @@ -43,7 +43,7 @@ test("should use webhook component on API", async ({ page }) => { await page.waitForTimeout(1000); await page - .getByTestId("dataWebhook Input") + .getByTestId("dataWebhook") .dragTo(page.locator('//*[@id="react-flow-id"]')); await page.mouse.up(); await page.mouse.down(); @@ -73,6 +73,4 @@ test("should use webhook component on API", async ({ page }) => { expect(clipboardContent).toContain("curl -X POST"); expect(clipboardContent).toContain("webhook"); await page.getByRole("tab", { name: "Tweaks" }).click(); - // await page.getByText("Webhook Input").isVisible(); - // await page.getByText("Webhook Input").click(); });