diff --git a/src/backend/base/langflow/base/flow_processing/utils.py b/src/backend/base/langflow/base/flow_processing/utils.py index 467a7a953..1505207ba 100644 --- a/src/backend/base/langflow/base/flow_processing/utils.py +++ b/src/backend/base/langflow/base/flow_processing/utils.py @@ -4,6 +4,7 @@ from loguru import logger from langflow.graph.schema import ResultData, RunOutputs from langflow.schema import Data +from langflow.schema.message import Message def build_data_from_run_outputs(run_outputs: RunOutputs) -> List[Data]: @@ -65,14 +66,17 @@ def build_data_from_result_data(result_data: ResultData, get_final_results_only: else: return [] - for message in messages: # type: ignore - message_dict = message if isinstance(message, dict) else message.model_dump() - if get_final_results_only: - result_data_dict = result_data.model_dump() - results = result_data_dict.get("results", {}) - inner_result = results.get("result", {}) - record = Data(data={"result": inner_result, "message": message_dict}, text_key="result") - data.append(record) + if isinstance(result_data.results, dict): + for name, result in result_data.results.items(): + dataobj: Data | Message | None = None + if isinstance(result, Message): + dataobj = result + else: + dataobj = Data(data=result, text_key=name) + + data.append(dataobj) + else: + data.append(Data(data=result_data.results)) return data @@ -88,5 +92,5 @@ def format_flow_output_data(data: List[Data]) -> str: """ result = "Flow run output:\n" - results = "\n".join([value.result for value in data if value.data["message"]]) + results = "\n".join([value.get_text() if hasattr(value, "get_text") else str(value) for value in data]) return result + results diff --git a/src/backend/base/langflow/components/prototypes/FlowTool.py b/src/backend/base/langflow/components/prototypes/FlowTool.py index d4a038e6f..add3d6dd0 100644 --- a/src/backend/base/langflow/components/prototypes/FlowTool.py +++ b/src/backend/base/langflow/components/prototypes/FlowTool.py @@ -1,17 +1,17 @@ from typing import Any, List, Optional -from loguru import logger +from langflow.base.langchain_utilities.model import LCToolComponent from langflow.base.tools.flow_tool import FlowTool -from langflow.custom import CustomComponent from langflow.field_typing import Tool from langflow.graph.graph.base import Graph from langflow.helpers.flow import get_flow_inputs +from langflow.io import BoolInput, DropdownInput, StrInput, Output from langflow.schema import Data from langflow.schema.dotdict import dotdict -class FlowToolComponent(CustomComponent): +class FlowToolComponent(LCToolComponent): display_name = "Flow as Tool" description = "Construct a Tool from a function that runs the loaded Flow." field_order = ["flow_name", "name", "description", "return_direct"] @@ -40,48 +40,49 @@ class FlowToolComponent(CustomComponent): return None def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None): - logger.debug(f"Updating build config with field value {field_value} and field name {field_name}") if field_name == "flow_name": build_config["flow_name"]["options"] = self.get_flow_names() return build_config - def build_config(self): - return { - "flow_name": { - "display_name": "Flow Name", - "info": "The name of the flow to run.", - "options": [], - "real_time_refresh": True, - "refresh_button": True, - }, - "name": { - "display_name": "Name", - "description": "The name of the tool.", - }, - "description": { - "display_name": "Description", - "description": "The description of the tool.", - }, - "return_direct": { - "display_name": "Return Direct", - "description": "Return the result directly from the Tool.", - "advanced": True, - }, - } + inputs = [ + DropdownInput( + name="flow_name", display_name="Flow Name", info="The name of the flow to run.", refresh_button=True + ), + StrInput( + name="name", + display_name="Name", + info="The name of the tool.", + ), + StrInput( + name="description", + display_name="Description", + info="The description of the tool.", + ), + BoolInput( + name="return_direct", + display_name="Return Direct", + info="Return the result directly from the Tool.", + advanced=True, + ), + ] - async def build(self, flow_name: str, name: str, description: str, return_direct: bool = False) -> Tool: + outputs = [ + Output(name="api_build_tool", display_name="Tool", method="build_tool"), + ] + + def build_tool(self) -> Tool: FlowTool.update_forward_refs() - flow_data = self.get_flow(flow_name) + flow_data = self.get_flow(self.flow_name) if not flow_data: raise ValueError("Flow not found.") graph = Graph.from_payload(flow_data.data["data"]) inputs = get_flow_inputs(graph) tool = FlowTool( - name=name, - description=description, + name=self.name, + description=self.description, graph=graph, - return_direct=return_direct, + return_direct=self.return_direct, inputs=inputs, flow_id=str(flow_data.id), user_id=str(self._user_id), diff --git a/src/backend/base/langflow/custom/custom_component/custom_component.py b/src/backend/base/langflow/custom/custom_component/custom_component.py index 753328aa0..c5e10932f 100644 --- a/src/backend/base/langflow/custom/custom_component/custom_component.py +++ b/src/backend/base/langflow/custom/custom_component/custom_component.py @@ -480,7 +480,7 @@ class CustomComponent(BaseComponent): inputs: Optional[Union[dict, List[dict]]] = None, flow_id: Optional[str] = None, flow_name: Optional[str] = None, - output_type: Optional[str] = None, + output_type: Optional[str] = "chat", tweaks: Optional[dict] = None, ) -> Any: return await run_flow( diff --git a/src/backend/base/langflow/helpers/flow.py b/src/backend/base/langflow/helpers/flow.py index de0a14d89..72075253f 100644 --- a/src/backend/base/langflow/helpers/flow.py +++ b/src/backend/base/langflow/helpers/flow.py @@ -71,7 +71,7 @@ async def run_flow( tweaks: Optional[dict] = None, flow_id: Optional[str] = None, flow_name: Optional[str] = None, - output_type: Optional[str] = None, + output_type: Optional[str] = "chat", user_id: Optional[str] = None, ) -> List[RunOutputs]: if user_id is None: