From b450e6604679aafb2a5948a597751d7afeaa28ce Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 1 Mar 2024 08:00:46 -0300 Subject: [PATCH] Update conditional paths in BranchComponent and ShouldRunNext --- .../langflow/components/utilities/Branch.py | 4 ++-- .../components/utilities/ShouldRunNext.py | 7 +++++-- .../langflow/interface/custom/attributes.py | 8 ++++++- .../custom_component/custom_component.py | 4 ++-- src/backend/langflow/schema.py | 21 ++++++++++++++++--- .../langflow/template/frontend_node/base.py | 5 ++--- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/backend/langflow/components/utilities/Branch.py b/src/backend/langflow/components/utilities/Branch.py index 3e786b7b9..fc6d414ab 100644 --- a/src/backend/langflow/components/utilities/Branch.py +++ b/src/backend/langflow/components/utilities/Branch.py @@ -6,11 +6,11 @@ from langflow.schema import Decision class BranchComponent(CustomComponent): display_name: str = "Branch Component" documentation: str = "http://docs.langflow.org/components/custom" - is_conditional = True + conditional_paths: list[str] = ["True", "False"] def build_config(self): return {"param": {"display_name": "Parameter"}} def build(self, param: Text) -> Text: - return Decision(path=True, result=param) + return Decision(path="True", result=param) diff --git a/src/backend/langflow/components/utilities/ShouldRunNext.py b/src/backend/langflow/components/utilities/ShouldRunNext.py index bdc328884..5270e4d34 100644 --- a/src/backend/langflow/components/utilities/ShouldRunNext.py +++ b/src/backend/langflow/components/utilities/ShouldRunNext.py @@ -49,6 +49,9 @@ class ShouldRunNext(CustomComponent): ) # The string should be the words true or false # if not raise an error - bool_result = result.lower() == "true" + if result.lower() not in ["true", "false"]: + raise ValueError( + "The prompt should generate a boolean response (True or False)." + ) - return Decision(path=bool_result, result=kwargs) + return Decision(path=result, result=kwargs) diff --git a/src/backend/langflow/interface/custom/attributes.py b/src/backend/langflow/interface/custom/attributes.py index 071d3f2b2..2524c0677 100644 --- a/src/backend/langflow/interface/custom/attributes.py +++ b/src/backend/langflow/interface/custom/attributes.py @@ -31,6 +31,12 @@ def getattr_return_bool(value): return value +def getattr_return_list_of_str(value): + if isinstance(value, list): + return [str(val) for val in value] + return [] + + ATTR_FUNC_MAPPING: dict[str, Callable] = { "display_name": getattr_return_str, "description": getattr_return_str, @@ -40,5 +46,5 @@ ATTR_FUNC_MAPPING: dict[str, Callable] = { "pinned": getattr_return_bool, "is_input": getattr_return_bool, "is_output": getattr_return_bool, - "is_conditional": getattr_return_bool, + "conditional_paths": getattr_return_list_of_str, } diff --git a/src/backend/langflow/interface/custom/custom_component/custom_component.py b/src/backend/langflow/interface/custom/custom_component/custom_component.py index 2c1ac57fc..57ded0d10 100644 --- a/src/backend/langflow/interface/custom/custom_component/custom_component.py +++ b/src/backend/langflow/interface/custom/custom_component/custom_component.py @@ -66,8 +66,8 @@ class CustomComponent(Component): """The selected output type of the component. Defaults to None.""" vertex: Optional["Vertex"] = None """The edge target parameter of the component. Defaults to None.""" - is_conditional: Optional[bool] = False - """The conditional state of the component. Defaults to False.""" + conditional_paths: Optional[List[str]] = None + """The conditional paths of the component. Defaults to None.""" code_class_base_inheritance: ClassVar[str] = "CustomComponent" function_entrypoint_name: ClassVar[str] = "build" function: Optional[Callable] = None diff --git a/src/backend/langflow/schema.py b/src/backend/langflow/schema.py index bfc8f8efa..44ee4532d 100644 --- a/src/backend/langflow/schema.py +++ b/src/backend/langflow/schema.py @@ -1,7 +1,7 @@ from typing import Any from langchain_core.documents import Document -from pydantic import BaseModel +from pydantic import BaseModel, field_validator class Record(BaseModel): @@ -79,9 +79,24 @@ class Decision(BaseModel): Represents a decision made in the Graph. Attributes: - path (bool): The path taken in the Graph. + path (str): The path to take as a result of the decision. result (dict): The result of the decision. """ - path: bool + path: str result: Any + + @field_validator("path") + def validate_path(cls, value: str) -> str: + """ + Validates the path. + + Args: + value (str): The path to validate. + + Returns: + str: The validated path. + """ + if isinstance(value, str): + return value + return str(value) diff --git a/src/backend/langflow/template/frontend_node/base.py b/src/backend/langflow/template/frontend_node/base.py index 2d79da2f3..c0f74ed0e 100644 --- a/src/backend/langflow/template/frontend_node/base.py +++ b/src/backend/langflow/template/frontend_node/base.py @@ -73,9 +73,8 @@ class FrontendNode(BaseModel): """Field formatters for the frontend node.""" pinned: bool = False """Whether the frontend node is pinned.""" - is_conditional: bool = False - """Whether the frontend node is conditional. This is used for the frontend node to show two output handles.""" - + conditional_paths: List[str] = [] + """List of conditional paths for the frontend node.""" beta: bool = False error: Optional[str] = None