From c5671f132f49f4d1a84c4eb9403307a9feb91de1 Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Wed, 6 Mar 2024 14:32:04 -0300 Subject: [PATCH] Add experimental components for listing flows, getting notified, and executing runnables --- .../{helpers => experimental}/GetNotified.py | 0 .../{helpers => experimental}/ListFlows.py | 0 .../{helpers => experimental}/Notify.py | 0 .../{helpers => experimental}/RunFlow.py | 0 .../RunnableExecutor.py | 0 .../{helpers => experimental}/SQLExecutor.py | 16 +++++- .../components/experimental/__init__.py | 0 .../components/helpers/SharedState.py | 41 ---------------- .../components/helpers/ShouldRunNext.py | 49 ------------------- 9 files changed, 14 insertions(+), 92 deletions(-) rename src/backend/langflow/components/{helpers => experimental}/GetNotified.py (100%) rename src/backend/langflow/components/{helpers => experimental}/ListFlows.py (100%) rename src/backend/langflow/components/{helpers => experimental}/Notify.py (100%) rename src/backend/langflow/components/{helpers => experimental}/RunFlow.py (100%) rename src/backend/langflow/components/{helpers => experimental}/RunnableExecutor.py (100%) rename src/backend/langflow/components/{helpers => experimental}/SQLExecutor.py (76%) create mode 100644 src/backend/langflow/components/experimental/__init__.py delete mode 100644 src/backend/langflow/components/helpers/SharedState.py delete mode 100644 src/backend/langflow/components/helpers/ShouldRunNext.py diff --git a/src/backend/langflow/components/helpers/GetNotified.py b/src/backend/langflow/components/experimental/GetNotified.py similarity index 100% rename from src/backend/langflow/components/helpers/GetNotified.py rename to src/backend/langflow/components/experimental/GetNotified.py diff --git a/src/backend/langflow/components/helpers/ListFlows.py b/src/backend/langflow/components/experimental/ListFlows.py similarity index 100% rename from src/backend/langflow/components/helpers/ListFlows.py rename to src/backend/langflow/components/experimental/ListFlows.py diff --git a/src/backend/langflow/components/helpers/Notify.py b/src/backend/langflow/components/experimental/Notify.py similarity index 100% rename from src/backend/langflow/components/helpers/Notify.py rename to src/backend/langflow/components/experimental/Notify.py diff --git a/src/backend/langflow/components/helpers/RunFlow.py b/src/backend/langflow/components/experimental/RunFlow.py similarity index 100% rename from src/backend/langflow/components/helpers/RunFlow.py rename to src/backend/langflow/components/experimental/RunFlow.py diff --git a/src/backend/langflow/components/helpers/RunnableExecutor.py b/src/backend/langflow/components/experimental/RunnableExecutor.py similarity index 100% rename from src/backend/langflow/components/helpers/RunnableExecutor.py rename to src/backend/langflow/components/experimental/RunnableExecutor.py diff --git a/src/backend/langflow/components/helpers/SQLExecutor.py b/src/backend/langflow/components/experimental/SQLExecutor.py similarity index 76% rename from src/backend/langflow/components/helpers/SQLExecutor.py rename to src/backend/langflow/components/experimental/SQLExecutor.py index 530391c31..e1b4e699f 100644 --- a/src/backend/langflow/components/helpers/SQLExecutor.py +++ b/src/backend/langflow/components/experimental/SQLExecutor.py @@ -11,7 +11,10 @@ class SQLExecutorComponent(CustomComponent): def build_config(self): return { - "database": {"display_name": "Database"}, + "database_url": { + "display_name": "Database URL", + "info": "The URL of the database.", + }, "include_columns": { "display_name": "Include Columns", "info": "Include columns in the result.", @@ -26,15 +29,24 @@ class SQLExecutorComponent(CustomComponent): }, } + def clean_up_uri(self, uri: str) -> str: + if uri.startswith("postgresql://"): + uri = uri.replace("postgresql://", "postgres://") + return uri.strip() + def build( self, query: str, - database: SQLDatabase, + database_url: str, include_columns: bool = False, passthrough: bool = False, add_error: bool = False, ) -> Text: error = None + try: + database = SQLDatabase.from_uri(database_url) + except Exception as e: + raise ValueError(f"An error occurred while connecting to the database: {e}") try: tool = QuerySQLDataBaseTool(db=database) result = tool.run(query, include_columns=include_columns) diff --git a/src/backend/langflow/components/experimental/__init__.py b/src/backend/langflow/components/experimental/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/backend/langflow/components/helpers/SharedState.py b/src/backend/langflow/components/helpers/SharedState.py deleted file mode 100644 index 95de17774..000000000 --- a/src/backend/langflow/components/helpers/SharedState.py +++ /dev/null @@ -1,41 +0,0 @@ -from typing import Optional - -from langflow import CustomComponent -from langflow.schema import Record - - -class SharedState(CustomComponent): - display_name = "Shared State" - description = "A component to share state between components." - - def build_config(self): - return { - "name": {"display_name": "Name", "info": "The name of the state."}, - "record": {"display_name": "Record", "info": "The record to store."}, - "append": { - "display_name": "Append", - "info": "If True, the record will be appended to the state.", - }, - } - - def build( - self, name: str, record: Optional[Record] = None, append: bool = False - ) -> Record: - if record: - if append: - self.append_state(name, record) - else: - self.update_state(name, record) - - state = self.get_state(name) - if state and not isinstance(state, Record): - if isinstance(state, str): - state = Record(text=state) - elif isinstance(state, dict): - state = Record(data=state) - else: - state = Record(text=str(state)) - elif not state: - state = Record(text="") - self.status = state - return state diff --git a/src/backend/langflow/components/helpers/ShouldRunNext.py b/src/backend/langflow/components/helpers/ShouldRunNext.py deleted file mode 100644 index b9ae3b048..000000000 --- a/src/backend/langflow/components/helpers/ShouldRunNext.py +++ /dev/null @@ -1,49 +0,0 @@ -# Implement ShouldRunNext component -from typing import Text -from langchain_core.prompts import PromptTemplate - -from langflow import CustomComponent -from langflow.field_typing import BaseLanguageModel, Prompt - - -class ShouldRunNext(CustomComponent): - display_name = "Should Run Next" - description = "Decides whether to run the next component." - - def build_config(self): - return { - "prompt": { - "display_name": "Prompt", - "info": "The prompt to use for the decision. It should generate a boolean response (True or False).", - }, - "llm": { - "display_name": "LLM", - "info": "The language model to use for the decision.", - }, - } - - def build(self, template: Prompt, llm: BaseLanguageModel, **kwargs) -> dict: - # This is a simple component that always returns True - prompt_template = PromptTemplate.from_template(Text(template)) - - attributes_to_check = ["text", "page_content"] - for key, value in kwargs.items(): - for attribute in attributes_to_check: - if hasattr(value, attribute): - kwargs[key] = getattr(value, attribute) - - chain = prompt_template | llm - result = chain.invoke(kwargs) - if hasattr(result, "content") and isinstance(result.content, str): - result = result.content - elif isinstance(result, str): - result = result - else: - result = result.get("response") - - if result.lower() not in ["true", "false"]: - raise ValueError("The prompt should generate a boolean response (True or False).") - # The string should be the words true or false - # if not raise an error - bool_result = result.lower() == "true" - return {"condition": bool_result, "result": kwargs}