refactor: improve attribute compatibility and error messages (#3367)

* feat: Refactor how configuration attributes are handled in Component class.

* refactor: Update method name to handle singular and plural inputs.

* refactor: Add value validation for input and attribute assignment.

* test: Add test for setting invalid input in task component.

* fix: add param without underscore to inputs

* test(astra): Refactor AstraDB imports in test_astra_component (#3413)

* test(astra): Refactor AstraDB imports in test_astra_component

* fix: Add AstraVectorizeComponent to AstraDB tests.

* fix: Refactor custom component error message for setting parameter or attribute.

* test(astra): Refactor AstraDB imports in test_astra_component (#3413)

* test(astra): Refactor AstraDB imports in test_astra_component

* fix: Add AstraVectorizeComponent to AstraDB tests.

* chore: Refactor joining methods list in _set_parameter_or_attribute function.

* refactor: Refactor error message string formatting in Component class.
This commit is contained in:
Gabriel Luiz Freitas Almeida 2024-08-21 09:34:15 -03:00 committed by GitHub
commit bf650ecec5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 36 additions and 1 deletions

View file

@ -26,6 +26,7 @@ if TYPE_CHECKING:
from langflow.inputs.inputs import InputTypes
BACKWARDS_COMPATIBLE_ATTRIBUTES = ["user_id", "vertex", "tracing_service"]
CONFIG_ATTRIBUTES = ["_display_name", "_description", "_icon", "_name"]
class Component(CustomComponent):
@ -43,6 +44,8 @@ class Component(CustomComponent):
for key, value in kwargs.items():
if key.startswith("_"):
config[key] = value
elif key in CONFIG_ATTRIBUTES:
config[key[1:]] = value
else:
inputs[key] = value
self._inputs: dict[str, "InputTypes"] = {}
@ -142,7 +145,7 @@ class Component(CustomComponent):
KeyError: If the specified input name does not exist.
"""
for key, value in kwargs.items():
self._process_connection_or_parameter(key, value)
self._process_connection_or_parameters(key, value)
return self
def list_inputs(self):
@ -320,6 +323,14 @@ class Component(CustomComponent):
else:
self._set_parameter_or_attribute(key, value)
def _process_connection_or_parameters(self, key, value):
# if value is a list of components, we need to process each component
if isinstance(value, list):
for val in value:
self._process_connection_or_parameter(key, val)
else:
self._process_connection_or_parameter(key, value)
def _get_or_create_input(self, key):
try:
return self._inputs[key]
@ -358,6 +369,12 @@ class Component(CustomComponent):
)
def _set_parameter_or_attribute(self, key, value):
if isinstance(value, Component):
methods = ", ".join([f"'{output.method}'" for output in value.outputs])
raise ValueError(
f"You set {value.display_name} as value for `{key}`. "
f"You should pass one of the following: {methods}"
)
self._set_input_value(key, value)
self._parameters[key] = value
self._attributes[key] = value
@ -396,6 +413,12 @@ class Component(CustomComponent):
def _set_input_value(self, name: str, value: Any):
if name in self._inputs:
input_value = self._inputs[name].value
if isinstance(input_value, Component):
methods = ", ".join([f"'{output.method}'" for output in input_value.outputs])
raise ValueError(
f"You set {input_value.display_name} as value for `{name}`. "
f"You should pass one of the following: {methods}"
)
if callable(input_value):
raise ValueError(
f"Input {name} is connected to {input_value.__self__.display_name}.{input_value.__name__}"

View file

@ -1,5 +1,7 @@
import pytest
from langflow.components.agents.CrewAIAgent import CrewAIAgentComponent
from langflow.components.helpers.SequentialTask import SequentialTaskComponent
from langflow.components.inputs.ChatInput import ChatInput
from langflow.components.outputs import ChatOutput
@ -14,3 +16,13 @@ def test_set_invalid_output():
chatoutput = ChatOutput()
with pytest.raises(ValueError):
chatoutput.set(input_value=chatinput.build_config)
def test_set_invalid_input():
crewai_agent = CrewAIAgentComponent()
task = SequentialTaskComponent()
with pytest.raises(
ValueError,
match="You set CrewAI Agent as value for `agent`. You should pass one of the following: 'build_output'",
):
task.set(agent=crewai_agent)