diff --git a/src/backend/base/langflow/components/agents/__init__.py b/src/backend/base/langflow/components/agents/__init__.py index 245c38a97..93c5ac8b3 100644 --- a/src/backend/base/langflow/components/agents/__init__.py +++ b/src/backend/base/langflow/components/agents/__init__.py @@ -1,3 +1,4 @@ +from .agent import AgentComponent from .crewai import CrewAIAgentComponent from .csv import CSVAgentComponent from .hierarchical_crew import HierarchicalCrewComponent @@ -26,4 +27,5 @@ __all__ = [ "VectorStoreAgentComponent", "VectorStoreRouterAgentComponent", "XMLAgentComponent", + "AgentComponent", ] diff --git a/src/backend/base/langflow/components/models/openai.py b/src/backend/base/langflow/components/models/openai.py index f4a8be80f..d35f54dea 100644 --- a/src/backend/base/langflow/components/models/openai.py +++ b/src/backend/base/langflow/components/models/openai.py @@ -10,6 +10,7 @@ from langflow.field_typing import LanguageModel 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): @@ -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 diff --git a/src/backend/base/langflow/custom/custom_component/component.py b/src/backend/base/langflow/custom/custom_component/component.py index 8f6e2e9ea..c783079c7 100644 --- a/src/backend/base/langflow/custom/custom_component/component.py +++ b/src/backend/base/langflow/custom/custom_component/component.py @@ -369,6 +369,8 @@ class Component(CustomComponent): 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) diff --git a/src/backend/tests/unit/custom/custom_component/test_component.py b/src/backend/tests/unit/custom/custom_component/test_component.py index 4c03f827e..9827cc83e 100644 --- a/src/backend/tests/unit/custom/custom_component/test_component.py +++ b/src/backend/tests/unit/custom/custom_component/test_component.py @@ -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 @@ -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() - openai_component = OpenAIModelComponent() - - 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) - assert all( - _output_required_inputs_are_in_inputs(output, tool_calling_agent._inputs) - for output in tool_calling_agent.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(chatinput.outputs) - assert _assert_all_outputs_have_different_required_inputs(chatoutput.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) + + +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_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, agent_component._inputs) for output in agent_component.outputs + ) + assert _assert_all_outputs_have_different_required_inputs(agent_component.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)