From 5174c0638d18059894b20977b3a89dcfa531bf1b Mon Sep 17 00:00:00 2001 From: Edwin Jose Date: Tue, 3 Jun 2025 13:58:53 -0500 Subject: [PATCH] ref: ConditionalRouter Initialization with Case Sensitivity and renaming inputs (#8337) * Update conditional_router.py * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../base/langflow/components/logic/conditional_router.py | 6 ++++-- .../initial_setup/starter_projects/Youtube Analysis.json | 8 ++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/backend/base/langflow/components/logic/conditional_router.py b/src/backend/base/langflow/components/logic/conditional_router.py index c6cdec095..3649572f6 100644 --- a/src/backend/base/langflow/components/logic/conditional_router.py +++ b/src/backend/base/langflow/components/logic/conditional_router.py @@ -40,12 +40,14 @@ class ConditionalRouterComponent(Component): name="case_sensitive", display_name="Case Sensitive", info="If true, the comparison will be case sensitive.", - value=False, + value=True, + advanced=True, ), MessageInput( name="message", - display_name="Message", + display_name="Alternative Output", info="The message to pass through either route.", + advanced=True, ), IntInput( name="max_iterations", diff --git a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json index b3617aa21..bec30b2d8 100644 --- a/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json +++ b/src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json @@ -3026,7 +3026,7 @@ "_type": "Component", "case_sensitive": { "_input_type": "BoolInput", - "advanced": false, + "advanced": true, "display_name": "Case Sensitive", "dynamic": false, "info": "If true, the comparison will be case sensitive.", @@ -3058,7 +3058,7 @@ "show": true, "title_case": false, "type": "code", - "value": "import re\n\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ConditionalRouterComponent(Component):\n display_name = \"If-Else\"\n description = \"Routes an input message to a corresponding output based on text comparison.\"\n icon = \"split\"\n name = \"ConditionalRouter\"\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.__iteration_updated = False\n\n inputs = [\n MessageTextInput(\n name=\"input_text\",\n display_name=\"Text Input\",\n info=\"The primary text input for the operation.\",\n required=True,\n ),\n MessageTextInput(\n name=\"match_text\",\n display_name=\"Match Text\",\n info=\"The text input to compare against.\",\n required=True,\n ),\n DropdownInput(\n name=\"operator\",\n display_name=\"Operator\",\n options=[\"equals\", \"not equals\", \"contains\", \"starts with\", \"ends with\", \"regex\"],\n info=\"The operator to apply for comparing the texts.\",\n value=\"equals\",\n real_time_refresh=True,\n ),\n BoolInput(\n name=\"case_sensitive\",\n display_name=\"Case Sensitive\",\n info=\"If true, the comparison will be case sensitive.\",\n value=False,\n ),\n MessageInput(\n name=\"message\",\n display_name=\"Message\",\n info=\"The message to pass through either route.\",\n ),\n IntInput(\n name=\"max_iterations\",\n display_name=\"Max Iterations\",\n info=\"The maximum number of iterations for the conditional router.\",\n value=10,\n advanced=True,\n ),\n DropdownInput(\n name=\"default_route\",\n display_name=\"Default Route\",\n options=[\"true_result\", \"false_result\"],\n info=\"The default route to take when max iterations are reached.\",\n value=\"false_result\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"True\", name=\"true_result\", method=\"true_response\", group_outputs=True),\n Output(display_name=\"False\", name=\"false_result\", method=\"false_response\", group_outputs=True),\n ]\n\n def _pre_run_setup(self):\n self.__iteration_updated = False\n\n def evaluate_condition(self, input_text: str, match_text: str, operator: str, *, case_sensitive: bool) -> bool:\n if not case_sensitive and operator != \"regex\":\n input_text = input_text.lower()\n match_text = match_text.lower()\n\n if operator == \"equals\":\n return input_text == match_text\n if operator == \"not equals\":\n return input_text != match_text\n if operator == \"contains\":\n return match_text in input_text\n if operator == \"starts with\":\n return input_text.startswith(match_text)\n if operator == \"ends with\":\n return input_text.endswith(match_text)\n if operator == \"regex\":\n try:\n return bool(re.match(match_text, input_text))\n except re.error:\n return False # Return False if the regex is invalid\n return False\n\n def iterate_and_stop_once(self, route_to_stop: str):\n if not self.__iteration_updated:\n self.update_ctx({f\"{self._id}_iteration\": self.ctx.get(f\"{self._id}_iteration\", 0) + 1})\n self.__iteration_updated = True\n if self.ctx.get(f\"{self._id}_iteration\", 0) >= self.max_iterations and route_to_stop == self.default_route:\n route_to_stop = \"true_result\" if route_to_stop == \"false_result\" else \"false_result\"\n self.stop(route_to_stop)\n\n def true_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if result:\n self.status = self.message\n self.iterate_and_stop_once(\"false_result\")\n return self.message\n self.iterate_and_stop_once(\"true_result\")\n return Message(content=\"\")\n\n def false_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if not result:\n self.status = self.message\n self.iterate_and_stop_once(\"true_result\")\n return self.message\n self.iterate_and_stop_once(\"false_result\")\n return Message(content=\"\")\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n if field_name == \"operator\":\n if field_value == \"regex\":\n build_config.pop(\"case_sensitive\", None)\n\n # Ensure case_sensitive is present for all other operators\n elif \"case_sensitive\" not in build_config:\n case_sensitive_input = next(\n (input_field for input_field in self.inputs if input_field.name == \"case_sensitive\"), None\n )\n if case_sensitive_input:\n build_config[\"case_sensitive\"] = case_sensitive_input.to_dict()\n return build_config\n" + "value": "import re\n\nfrom langflow.custom import Component\nfrom langflow.io import BoolInput, DropdownInput, IntInput, MessageInput, MessageTextInput, Output\nfrom langflow.schema.message import Message\n\n\nclass ConditionalRouterComponent(Component):\n display_name = \"If-Else\"\n description = \"Routes an input message to a corresponding output based on text comparison.\"\n icon = \"split\"\n name = \"ConditionalRouter\"\n\n def __init__(self, *args, **kwargs):\n super().__init__(*args, **kwargs)\n self.__iteration_updated = False\n\n inputs = [\n MessageTextInput(\n name=\"input_text\",\n display_name=\"Text Input\",\n info=\"The primary text input for the operation.\",\n required=True,\n ),\n MessageTextInput(\n name=\"match_text\",\n display_name=\"Match Text\",\n info=\"The text input to compare against.\",\n required=True,\n ),\n DropdownInput(\n name=\"operator\",\n display_name=\"Operator\",\n options=[\"equals\", \"not equals\", \"contains\", \"starts with\", \"ends with\", \"regex\"],\n info=\"The operator to apply for comparing the texts.\",\n value=\"equals\",\n real_time_refresh=True,\n ),\n BoolInput(\n name=\"case_sensitive\",\n display_name=\"Case Sensitive\",\n info=\"If true, the comparison will be case sensitive.\",\n value=True,\n advanced=True,\n ),\n MessageInput(\n name=\"message\",\n display_name=\"Alternative Output\",\n info=\"The message to pass through either route.\",\n advanced=True,\n ),\n IntInput(\n name=\"max_iterations\",\n display_name=\"Max Iterations\",\n info=\"The maximum number of iterations for the conditional router.\",\n value=10,\n advanced=True,\n ),\n DropdownInput(\n name=\"default_route\",\n display_name=\"Default Route\",\n options=[\"true_result\", \"false_result\"],\n info=\"The default route to take when max iterations are reached.\",\n value=\"false_result\",\n advanced=True,\n ),\n ]\n\n outputs = [\n Output(display_name=\"True\", name=\"true_result\", method=\"true_response\", group_outputs=True),\n Output(display_name=\"False\", name=\"false_result\", method=\"false_response\", group_outputs=True),\n ]\n\n def _pre_run_setup(self):\n self.__iteration_updated = False\n\n def evaluate_condition(self, input_text: str, match_text: str, operator: str, *, case_sensitive: bool) -> bool:\n if not case_sensitive and operator != \"regex\":\n input_text = input_text.lower()\n match_text = match_text.lower()\n\n if operator == \"equals\":\n return input_text == match_text\n if operator == \"not equals\":\n return input_text != match_text\n if operator == \"contains\":\n return match_text in input_text\n if operator == \"starts with\":\n return input_text.startswith(match_text)\n if operator == \"ends with\":\n return input_text.endswith(match_text)\n if operator == \"regex\":\n try:\n return bool(re.match(match_text, input_text))\n except re.error:\n return False # Return False if the regex is invalid\n return False\n\n def iterate_and_stop_once(self, route_to_stop: str):\n if not self.__iteration_updated:\n self.update_ctx({f\"{self._id}_iteration\": self.ctx.get(f\"{self._id}_iteration\", 0) + 1})\n self.__iteration_updated = True\n if self.ctx.get(f\"{self._id}_iteration\", 0) >= self.max_iterations and route_to_stop == self.default_route:\n route_to_stop = \"true_result\" if route_to_stop == \"false_result\" else \"false_result\"\n self.stop(route_to_stop)\n\n def true_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if result:\n self.status = self.message\n self.iterate_and_stop_once(\"false_result\")\n return self.message\n self.iterate_and_stop_once(\"true_result\")\n return Message(content=\"\")\n\n def false_response(self) -> Message:\n result = self.evaluate_condition(\n self.input_text, self.match_text, self.operator, case_sensitive=self.case_sensitive\n )\n if not result:\n self.status = self.message\n self.iterate_and_stop_once(\"true_result\")\n return self.message\n self.iterate_and_stop_once(\"false_result\")\n return Message(content=\"\")\n\n def update_build_config(self, build_config: dict, field_value: str, field_name: str | None = None) -> dict:\n if field_name == \"operator\":\n if field_value == \"regex\":\n build_config.pop(\"case_sensitive\", None)\n\n # Ensure case_sensitive is present for all other operators\n elif \"case_sensitive\" not in build_config:\n case_sensitive_input = next(\n (input_field for input_field in self.inputs if input_field.name == \"case_sensitive\"), None\n )\n if case_sensitive_input:\n build_config[\"case_sensitive\"] = case_sensitive_input.to_dict()\n return build_config\n" }, "default_route": { "_input_type": "DropdownInput", @@ -3149,8 +3149,8 @@ }, "message": { "_input_type": "MessageInput", - "advanced": false, - "display_name": "Message", + "advanced": true, + "display_name": "Alternative Output", "dynamic": false, "info": "The message to pass through either route.", "input_types": [