Tai Truong
fix readme
d202ada
from typing import Any
from loguru import logger
from typing_extensions import override
from langflow.base.langchain_utilities.model import LCToolComponent
from langflow.base.tools.flow_tool import FlowTool
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, Output, StrInput
from langflow.schema import Data
from langflow.schema.dotdict import dotdict
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"]
trace_type = "tool"
name = "FlowTool"
beta = True
icon = "hammer"
def get_flow_names(self) -> list[str]:
flow_datas = self.list_flows()
return [flow_data.data["name"] for flow_data in flow_datas]
def get_flow(self, flow_name: str) -> Data | None:
"""Retrieves a flow by its name.
Args:
flow_name (str): The name of the flow to retrieve.
Returns:
Optional[Text]: The flow record if found, None otherwise.
"""
flow_datas = self.list_flows()
for flow_data in flow_datas:
if flow_data.data["name"] == flow_name:
return flow_data
return None
@override
def update_build_config(self, build_config: dotdict, field_value: Any, field_name: str | None = None):
if field_name == "flow_name":
build_config["flow_name"]["options"] = self.get_flow_names()
return build_config
inputs = [
DropdownInput(
name="flow_name", display_name="Flow Name", info="The name of the flow to run.", refresh_button=True
),
StrInput(
name="tool_name",
display_name="Name",
info="The name of the tool.",
),
StrInput(
name="tool_description",
display_name="Description",
info="The description of the tool; defaults to the Flow's description.",
),
BoolInput(
name="return_direct",
display_name="Return Direct",
info="Return the result directly from the Tool.",
advanced=True,
),
]
outputs = [
Output(name="api_build_tool", display_name="Tool", method="build_tool"),
]
def build_tool(self) -> Tool:
FlowTool.model_rebuild()
if "flow_name" not in self._attributes or not self._attributes["flow_name"]:
msg = "Flow name is required"
raise ValueError(msg)
flow_name = self._attributes["flow_name"]
flow_data = self.get_flow(flow_name)
if not flow_data:
msg = "Flow not found."
raise ValueError(msg)
graph = Graph.from_payload(
flow_data.data["data"],
user_id=str(self.user_id),
)
try:
graph.set_run_id(self.graph.run_id)
except Exception: # noqa: BLE001
logger.opt(exception=True).warning("Failed to set run_id")
inputs = get_flow_inputs(graph)
tool_description = self.tool_description.strip() or flow_data.description
tool = FlowTool(
name=self.tool_name,
description=tool_description,
graph=graph,
return_direct=self.return_direct,
inputs=inputs,
flow_id=str(flow_data.id),
user_id=str(self.user_id),
session_id=self.graph.session_id if hasattr(self, "graph") else None,
)
description_repr = repr(tool.description).strip("'")
args_str = "\n".join([f"- {arg_name}: {arg_data['description']}" for arg_name, arg_data in tool.args.items()])
self.status = f"{description_repr}\nArguments:\n{args_str}"
return tool