Skip to content

Commit

Permalink
fix: Optimize Setting of Output Required Inputs (langflow-ai#4389)
Browse files Browse the repository at this point in the history
Update component.py

Fix required inputs not updated if its already defined
  • Loading branch information
edwinjosechittilappilly authored and diogocabral committed Nov 26, 2024
1 parent 0d9e80c commit 99487e5
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
2 changes: 2 additions & 0 deletions src/backend/base/langflow/components/agents/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .agent import AgentComponent
from .crewai import CrewAIAgentComponent
from .csv import CSVAgentComponent
from .hierarchical_crew import HierarchicalCrewComponent
Expand Down Expand Up @@ -26,4 +27,5 @@
"VectorStoreAgentComponent",
"VectorStoreRouterAgentComponent",
"XMLAgentComponent",
"AgentComponent",
]
5 changes: 5 additions & 0 deletions src/backend/base/langflow/components/models/openai.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from langflow.field_typing.range_spec import RangeSpec
from langflow.inputs import BoolInput, DictInput, DropdownInput, FloatInput, IntInput, SecretStrInput, StrInput
from langflow.inputs.inputs import HandleInput
from langflow.io import Output


class OpenAIModelComponent(LCModelComponent):
Expand Down Expand Up @@ -81,6 +82,10 @@ class OpenAIModelComponent(LCModelComponent):
input_types=["OutputParser"],
),
]
outputs = [
Output(display_name="Text", name="text_output", method="text_response"),
Output(display_name="Language Model", name="model_output", method="build_model"),
]

def build_model(self) -> LanguageModel: # type: ignore[type-var]
# self.output_schema is a list of dictionaries
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ def _set_output_return_type(self, output: Output) -> None:

def _set_output_required_inputs(self) -> None:
for output in self.outputs:
if output.required_inputs:
continue
if not output.method:
continue
method = getattr(self, output.method, None)
Expand Down
45 changes: 28 additions & 17 deletions src/backend/tests/unit/custom/custom_component/test_component.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import pytest
from langflow.components.agents import CrewAIAgentComponent, ToolCallingAgentComponent
from langflow.components.agents import AgentComponent, CrewAIAgentComponent, ToolCallingAgentComponent
from langflow.components.helpers import SequentialTaskComponent
from langflow.components.inputs import ChatInput
from langflow.components.models import OpenAIModelComponent
Expand Down Expand Up @@ -32,33 +32,44 @@ def _assert_all_outputs_have_different_required_inputs(outputs: list[Output]):
return True


def test_set_required_inputs():
def test_set_required_inputs_chat_input():
chatinput = ChatInput()

assert all(_output_required_inputs_are_in_inputs(output, chatinput._inputs) for output in chatinput.outputs)
assert _assert_all_outputs_have_different_required_inputs(chatinput.outputs)


def test_set_required_inputs_various_components():
chatinput = ChatInput()
def test_set_required_inputs_chat_output():
chatoutput = ChatOutput()
task = SequentialTaskComponent()
tool_calling_agent = ToolCallingAgentComponent()
assert all(_output_required_inputs_are_in_inputs(output, chatoutput._inputs) for output in chatoutput.outputs)
assert _assert_all_outputs_have_different_required_inputs(chatoutput.outputs)


def test_set_required_inputs_openai_component():
openai_component = OpenAIModelComponent()
assert all(
_output_required_inputs_are_in_inputs(output, openai_component._inputs) for output in openai_component.outputs
)
assert _assert_all_outputs_have_different_required_inputs(openai_component.outputs)

assert all(_output_required_inputs_are_in_inputs(output, chatinput._inputs) for output in chatinput.outputs)
assert all(_output_required_inputs_are_in_inputs(output, chatoutput._inputs) for output in chatoutput.outputs)
assert all(_output_required_inputs_are_in_inputs(output, task._inputs) for output in task.outputs)

def test_set_required_inputs_tool_calling_agent_component():
tool_calling_agent_component = ToolCallingAgentComponent()
assert all(
_output_required_inputs_are_in_inputs(output, tool_calling_agent._inputs)
for output in tool_calling_agent.outputs
_output_required_inputs_are_in_inputs(output, tool_calling_agent_component._inputs)
for output in tool_calling_agent_component.outputs
)
assert _assert_all_outputs_have_different_required_inputs(tool_calling_agent_component.outputs)


def test_set_required_inputs_agent_component():
agent_component = AgentComponent()
assert all(
_output_required_inputs_are_in_inputs(output, openai_component._inputs) for output in openai_component.outputs
_output_required_inputs_are_in_inputs(output, agent_component._inputs) for output in agent_component.outputs
)
assert _assert_all_outputs_have_different_required_inputs(agent_component.outputs)

assert _assert_all_outputs_have_different_required_inputs(chatinput.outputs)
assert _assert_all_outputs_have_different_required_inputs(chatoutput.outputs)

def test_set_required_inputs_sequential_task_component():
task = SequentialTaskComponent()
assert all(_output_required_inputs_are_in_inputs(output, task._inputs) for output in task.outputs)
assert _assert_all_outputs_have_different_required_inputs(task.outputs)
assert _assert_all_outputs_have_different_required_inputs(tool_calling_agent.outputs)
assert _assert_all_outputs_have_different_required_inputs(openai_component.outputs)

0 comments on commit 99487e5

Please sign in to comment.