Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
620e6b4
bufix(cuga_agent): fixed no output chat bug
offerakrabi Nov 17, 2025
bc1d7bb
fix: remove structured output feature
sami-marreed Nov 17, 2025
128022f
Merge branch 'feature/new-cuga-release' of github.com:sami-marreed/la…
sami-marreed Nov 17, 2025
2d8c2c6
fix: stablize component
sami-marreed Nov 17, 2025
d0f5e0c
fix: chat output component not working
sami-marreed Nov 17, 2025
7f7ee7b
fix: add strategy flag
sami-marreed Nov 18, 2025
95d5359
fix: update cuga version
sami-marreed Nov 18, 2025
be5bf6b
Merge branch 'main' of https://github.com/langflow-ai/langflow into f…
sami-marreed Nov 18, 2025
9a52902
feat: add component index
sami-marreed Nov 18, 2025
af34ace
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 18, 2025
7f19707
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 18, 2025
3b26066
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 18, 2025
25f9fcb
update some imports to use lfx
jordanrfrazier Nov 18, 2025
2ddab31
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 18, 2025
a4334d1
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 18, 2025
280cadd
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 18, 2025
16809a6
fix: update review
sami-marreed Nov 18, 2025
03e48a1
chore: build component index
sami-marreed Nov 18, 2025
f423a12
chore: build component
sami-marreed Nov 18, 2025
aa350ab
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 18, 2025
716ccd6
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 18, 2025
26beab4
fix(cuga): ensure message id exists when not connected to output
sami-marreed Nov 19, 2025
caa9241
fix: component result id on chat output
sami-marreed Nov 19, 2025
4161d73
Merge branch 'feature/new-cuga-release' of github.com:sami-marreed/la…
sami-marreed Nov 19, 2025
725de68
fix: component result id on chat output
sami-marreed Nov 19, 2025
a4e33be
chore: fix component index
sami-marreed Nov 19, 2025
17d1f48
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 19, 2025
99b13aa
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 19, 2025
5d3a440
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 19, 2025
34c0bf8
Merge branch 'main' of https://github.com/langflow-ai/langflow into f…
sami-marreed Nov 19, 2025
cd789e1
Revert test_agent_component.py back to origin/main
sami-marreed Nov 19, 2025
24e968d
fix: remove unwanted tests
sami-marreed Nov 19, 2025
38fc66a
chore: new build index
sami-marreed Nov 19, 2025
6bea90e
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 19, 2025
dae85dd
fix: update test
sami-marreed Nov 19, 2025
0f08c6a
Merge branch 'feature/new-cuga-release' of github.com:sami-marreed/la…
sami-marreed Nov 19, 2025
3b17f8e
Merge branch 'main' of https://github.com/langflow-ai/langflow into f…
sami-marreed Nov 20, 2025
39280c6
chore: build index
sami-marreed Nov 20, 2025
236a0bc
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 20, 2025
3d77279
fix: update package of cuga
sami-marreed Nov 20, 2025
042d109
Merge branch 'feature/new-cuga-release' of github.com:sami-marreed/la…
sami-marreed Nov 20, 2025
400d4a5
chore: build component index
sami-marreed Nov 20, 2025
a63e0a2
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 20, 2025
79aaf8a
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 20, 2025
fa94107
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 20, 2025
0053bd6
update comp index
jordanrfrazier Nov 20, 2025
768d772
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 20, 2025
5745695
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 20, 2025
c3b78d0
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 20, 2025
d524a02
trying comp index again?
jordanrfrazier Nov 20, 2025
816bbe5
Merge branch 'main' into feature/new-cuga-release
jordanrfrazier Nov 21, 2025
9005e2b
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 21, 2025
135f043
[autofix.ci] apply automated fixes (attempt 2/3)
autofix-ci[bot] Nov 21, 2025
35a6887
[autofix.ci] apply automated fixes (attempt 3/3)
autofix-ci[bot] Nov 21, 2025
7b7188d
Merge branch 'main' into feature/new-cuga-release
jordanrfrazier Nov 21, 2025
93c80f7
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ dependencies = [
"fastparquet>=2024.11.0,<2025.0.0",
"traceloop-sdk>=0.43.1,<1.0.0",
"vlmrun[all]>=0.2.0",
"cuga==0.1.7",
"cuga==0.1.8",
"agent-lifecycle-toolkit~=0.4.1",
"astrapy>=2.1.0,<3.0.0",
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,261 +109,6 @@ async def test_build_config_update(self, component_class, default_kwargs):
# Verify model_name field is cleared for Custom
assert "model_name" not in updated_config

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_agent_has_dual_outputs(self, component_class, default_kwargs):
"""Test that Agent component has both Response and Structured Response outputs."""
component = await self.component_setup(component_class, default_kwargs)

assert len(component.outputs) == 2
assert component.outputs[0].name == "response"
assert component.outputs[0].display_name == "Response"
assert component.outputs[0].method == "message_response"

assert component.outputs[1].name == "structured_response"
assert component.outputs[1].display_name == "Structured Response"
assert component.outputs[1].method == "json_response"
assert component.outputs[1].tool_mode is False

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_json_mode_filtered_from_openai_inputs(self, component_class, default_kwargs):
"""Test that json_mode is filtered out from OpenAI inputs."""
component = await self.component_setup(component_class, default_kwargs)

# Check that json_mode is not in the agent's inputs
input_names = [inp.name for inp in component.inputs if hasattr(inp, "name")]
assert "json_mode" not in input_names

# Verify other OpenAI inputs are still present
assert "model_name" in input_names
assert "api_key" in input_names
assert "temperature" in input_names

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_json_response_parsing_valid_json(self, component_class, default_kwargs):
"""Test that json_response correctly parses JSON from agent response."""
component = await self.component_setup(component_class, default_kwargs)
# Mock the get_agent_requirements method to avoid actual LLM calls
from unittest.mock import AsyncMock

component.get_agent_requirements = AsyncMock(return_value=(MockLanguageModel(), [], []))
component.create_agent_runnable = AsyncMock(return_value=None)
mock_result = type("MockResult", (), {"content": '{"name": "test", "value": 123}'})()
component.run_agent = AsyncMock(return_value=mock_result)

result = await component.json_response()

from lfx.schema.data import Data

assert isinstance(result, Data)
assert result.data == {"name": "test", "value": 123}

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_json_response_parsing_embedded_json(self, component_class, default_kwargs):
"""Test that json_response handles text containing JSON."""
component = await self.component_setup(component_class, default_kwargs)
# Mock the get_agent_requirements method to avoid actual LLM calls
from unittest.mock import AsyncMock

component.get_agent_requirements = AsyncMock(return_value=(MockLanguageModel(), [], []))
component.create_agent_runnable = AsyncMock(return_value=None)
mock_result = type("MockResult", (), {"content": 'Here is the result: {"status": "success"} - done!'})()
component.run_agent = AsyncMock(return_value=mock_result)

result = await component.json_response()

from lfx.schema.data import Data

assert isinstance(result, Data)
assert result.data == {"status": "success"}

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_json_response_error_handling(self, component_class, default_kwargs):
"""Test that json_response handles completely non-JSON responses."""
component = await self.component_setup(component_class, default_kwargs)
# Mock the get_agent_requirements method to avoid actual LLM calls
from unittest.mock import AsyncMock

component.get_agent_requirements = AsyncMock(return_value=(MockLanguageModel(), [], []))
component.create_agent_runnable = AsyncMock(return_value=None)
mock_result = type("MockResult", (), {"content": "This is just plain text with no JSON"})()
component.run_agent = AsyncMock(return_value=mock_result)

result = await component.json_response()

from lfx.schema.data import Data

assert isinstance(result, Data)
assert "error" in result.data
assert result.data["content"] == "This is just plain text with no JSON"

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_model_building_without_json_mode(self, component_class, default_kwargs):
"""Test that model building works without json_mode attribute."""
component = await self.component_setup(component_class, default_kwargs)
component.agent_llm = "OpenAI"

# Mock component for testing
from unittest.mock import Mock

mock_component = Mock()
mock_component.set.return_value = mock_component

# Should not raise AttributeError for missing json_mode
result = component.set_component_params(mock_component)

assert result is not None
# Verify set was called (meaning no AttributeError occurred)
mock_component.set.assert_called_once()

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_json_response_with_schema_validation(self, component_class, default_kwargs):
"""Test that json_response validates against provided schema."""
# Set up component with output schema
default_kwargs["output_schema"] = [
{"name": "name", "type": "str", "description": "Name field", "multiple": False},
{"name": "age", "type": "int", "description": "Age field", "multiple": False},
]
component = await self.component_setup(component_class, default_kwargs)
# Mock the get_agent_requirements method
from unittest.mock import AsyncMock

component.get_agent_requirements = AsyncMock(return_value=(MockLanguageModel(), [], []))
component.create_agent_runnable = AsyncMock(return_value=None)
mock_result = type("MockResult", (), {"content": '{"name": "John", "age": 25}'})()
component.run_agent = AsyncMock(return_value=mock_result)

result = await component.json_response()

from langflow.schema.data import Data

assert isinstance(result, Data)
assert result.data == {"name": "John", "age": 25}

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_agent_component_initialization(self, component_class, default_kwargs):
"""Test that Agent component initializes correctly with filtered inputs."""
component = await self.component_setup(component_class, default_kwargs)

# Should not raise any errors during initialization
assert component.display_name == "Agent"
assert component.name == "Agent"
assert len(component.inputs) > 0
assert len(component.outputs) == 2

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_frontend_node_structure(self, component_class, default_kwargs):
"""Test that frontend node has correct structure with filtered inputs."""
component = await self.component_setup(component_class, default_kwargs)

frontend_node = component.to_frontend_node()
build_config = frontend_node["data"]["node"]["template"]

# Verify json_mode is not in build config
assert "json_mode" not in build_config

# Verify other expected fields are present
assert "agent_llm" in build_config
assert "system_prompt" in build_config
assert "add_current_date_tool" in build_config

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_preprocess_schema(self, component_class, default_kwargs):
"""Test that _preprocess_schema correctly handles schema validation."""
component = await self.component_setup(component_class, default_kwargs)

# Test schema preprocessing
raw_schema = [
{"name": "field1", "type": "str", "description": "Test field", "multiple": "true"},
{"name": "field2", "type": "int", "description": "Another field", "multiple": False},
]

processed = component._preprocess_schema(raw_schema)

assert len(processed) == 2
assert processed[0]["multiple"] is True # String "true" should be converted to bool
assert processed[1]["multiple"] is False

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_build_structured_output_base_with_validation(self, component_class, default_kwargs):
"""Test build_structured_output_base with schema validation."""
default_kwargs["output_schema"] = [
{"name": "name", "type": "str", "description": "Name field", "multiple": False},
{"name": "count", "type": "int", "description": "Count field", "multiple": False},
]
component = await self.component_setup(component_class, default_kwargs)

# Test valid JSON that matches schema
valid_content = '{"name": "test", "count": 42}'
result = await component.build_structured_output_base(valid_content)
assert result == [{"name": "test", "count": 42}]

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_build_structured_output_base_without_schema(self, component_class, default_kwargs):
"""Test build_structured_output_base without schema validation."""
component = await self.component_setup(component_class, default_kwargs)

# Test with no output_schema
content = '{"any": "data", "number": 123}'
result = await component.build_structured_output_base(content)
assert result == {"any": "data", "number": 123}

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_build_structured_output_base_embedded_json(self, component_class, default_kwargs):
"""Test extraction of JSON from embedded text."""
component = await self.component_setup(component_class, default_kwargs)

content = 'Here is some text with {"embedded": "json"} inside it.'
result = await component.build_structured_output_base(content)
assert result == {"embedded": "json"}

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_build_structured_output_base_no_json(self, component_class, default_kwargs):
"""Test handling of content with no JSON."""
component = await self.component_setup(component_class, default_kwargs)

content = "This is just plain text with no JSON at all."
result = await component.build_structured_output_base(content)
assert "error" in result
assert result["content"] == content

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_new_input_fields_present(self, component_class, default_kwargs):
"""Test that new input fields are present in the component."""
component = await self.component_setup(component_class, default_kwargs)

input_names = [inp.name for inp in component.inputs if hasattr(inp, "name")]

# Test for new fields
assert "format_instructions" in input_names
assert "output_schema" in input_names
assert "n_messages" in input_names

# Verify default values
assert hasattr(component, "format_instructions")
assert hasattr(component, "output_schema")
assert hasattr(component, "n_messages")
assert component.n_messages == 100

@pytest.mark.skip(reason="Test marked as skipped, agent dual output removed")
async def test_agent_has_correct_outputs(self, component_class, default_kwargs):
"""Test that Agent component has the correct output configuration."""
component = await self.component_setup(component_class, default_kwargs)

assert len(component.outputs) == 2

# Test response output
response_output = component.outputs[0]
assert response_output.name == "response"
assert response_output.display_name == "Response"
assert response_output.method == "message_response"

# Test structured response output
structured_output = component.outputs[1]
assert structured_output.name == "structured_response"
assert structured_output.display_name == "Structured Response"
assert structured_output.method == "json_response"
assert structured_output.tool_mode is False

async def test_agent_filters_empty_chat_history_messages(self):
"""Test that empty messages in chat history are filtered out."""
from lfx.base.agents.utils import data_to_messages
Expand Down
Loading
Loading