fix: validate params assignment in custom_component_update endpoint (#2931)

* feat(RunFlow.py): update input and output definitions for RunFlowComponent

* refactor: update params assignment in custom_component_update endpoint

Simplify the params assignment in the custom_component_update endpoint by using a dictionary comprehension. This improves code readability and reduces the number of lines.

* feat(custom_component.py, flow.py): add support for specifying output type in run_flow method to filter outputs based on type
This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-07-24 21:33:05 -03:00 • committed by GitHub
commit 7d5ccb324a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 25 deletions

View file

@ -590,7 +590,9 @@ async def custom_component_update(
) )
if hasattr(cc_instance, "set_attributes"): if hasattr(cc_instance, "set_attributes"):
template = code_request.get_template() template = code_request.get_template()
params = {key: value_dict["value"] for key, value_dict in template.items() if isinstance(value_dict, dict)} params = {
key: value_dict.get("value") for key, value_dict in template.items() if isinstance(value_dict, dict)
}
load_from_db_fields = [ load_from_db_fields = [
field_name field_name
for field_name, field_dict in template.items() for field_name, field_dict in template.items()

View file

@ -1,13 +1,13 @@
from typing import Any, List, Optional from typing import Any, List, Optional
from langflow.base.flow_processing.utils import build_data_from_run_outputs from langflow.base.flow_processing.utils import build_data_from_run_outputs
from langflow.custom import CustomComponent from langflow.custom import Component
from langflow.field_typing import NestedDict, Text
from langflow.graph.schema import RunOutputs from langflow.graph.schema import RunOutputs
from langflow.io import DropdownInput, MessageTextInput, NestedDictInput, Output
from langflow.schema import Data, dotdict from langflow.schema import Data, dotdict
class RunFlowComponent(CustomComponent): class RunFlowComponent(Component):
display_name = "Run Flow" display_name = "Run Flow"
description = "A component to run a flow." description = "A component to run a flow."
name = "RunFlow" name = "RunFlow"
@ -23,27 +23,33 @@ class RunFlowComponent(CustomComponent):
return build_config return build_config
def build_config(self): inputs = [
return { MessageTextInput(
"input_value": { name="input_value",
"display_name": "Input Value", display_name="Input Value",
"multiline": True, info="The input value to be processed by the flow.",
}, ),
"flow_name": { DropdownInput(
"display_name": "Flow Name", name="flow_name",
"info": "The name of the flow to run.", display_name="Flow Name",
"options": [], info="The name of the flow to run.",
"refresh_button": True, options=[],
}, refresh_button=True,
"tweaks": { ),
"display_name": "Tweaks", NestedDictInput(
"info": "Tweaks to apply to the flow.", name="tweaks",
}, display_name="Tweaks",
} info="Tweaks to apply to the flow.",
),
]
async def build(self, input_value: Text, flow_name: str, tweaks: NestedDict) -> List[Data]: outputs = [
Output(display_name="Run Outputs", name="run_outputs", method="generate_results"),
]
async def generate_results(self) -> List[Data]:
results: List[Optional[RunOutputs]] = await self.run_flow( results: List[Optional[RunOutputs]] = await self.run_flow(
inputs={"input_value": input_value}, flow_name=flow_name, tweaks=tweaks inputs={"input_value": self.input_value}, flow_name=self.flow_name, tweaks=self.tweaks
) )
if isinstance(results, list): if isinstance(results, list):
data = [] data = []

View file

@ -480,9 +480,17 @@ class CustomComponent(BaseComponent):
inputs: Optional[Union[dict, List[dict]]] = None, inputs: Optional[Union[dict, List[dict]]] = None,
flow_id: Optional[str] = None, flow_id: Optional[str] = None,
flow_name: Optional[str] = None, flow_name: Optional[str] = None,
output_type: Optional[str] = None,
tweaks: Optional[dict] = None, tweaks: Optional[dict] = None,
) -> Any: ) -> Any:
return await run_flow(inputs=inputs, flow_id=flow_id, flow_name=flow_name, tweaks=tweaks, user_id=self._user_id) return await run_flow(
inputs=inputs,
output_type=output_type,
flow_id=flow_id,
flow_name=flow_name,
tweaks=tweaks,
user_id=self._user_id,
)
def list_flows(self) -> List[Data]: def list_flows(self) -> List[Data]:
if not self._user_id: if not self._user_id:

View file

@ -71,6 +71,7 @@ async def run_flow(
tweaks: Optional[dict] = None, tweaks: Optional[dict] = None,
flow_id: Optional[str] = None, flow_id: Optional[str] = None,
flow_name: Optional[str] = None, flow_name: Optional[str] = None,
output_type: Optional[str] = None,
user_id: Optional[str] = None, user_id: Optional[str] = None,
) -> List[RunOutputs]: ) -> List[RunOutputs]:
if user_id is None: if user_id is None:
@ -89,10 +90,23 @@ async def run_flow(
inputs_components.append(input_dict.get("components", [])) inputs_components.append(input_dict.get("components", []))
types.append(input_dict.get("type", "chat")) types.append(input_dict.get("type", "chat"))
outputs = [
vertex.id
for vertex in graph.vertices
if output_type == "debug"
or (
vertex.is_output and (output_type == "any" or output_type in vertex.id.lower()) # type: ignore
)
]
fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var fallback_to_env_vars = get_settings_service().settings.fallback_to_env_var
return await graph.arun( return await graph.arun(
inputs_list, inputs_components=inputs_components, types=types, fallback_to_env_vars=fallback_to_env_vars inputs_list,
outputs=outputs,
inputs_components=inputs_components,
types=types,
fallback_to_env_vars=fallback_to_env_vars,
) )