Skip to content

feat: Add dual output support to Agent component with structured JSON parsing#8836

Merged
edwinjosechittilappilly merged 12 commits into
mainfrom
feature/agent-structured-output
Jul 21, 2025
Merged

feat: Add dual output support to Agent component with structured JSON parsing#8836
edwinjosechittilappilly merged 12 commits into
mainfrom
feature/agent-structured-output

Conversation

@rodrigosnader
Copy link
Copy Markdown
Contributor

@rodrigosnader rodrigosnader commented Jul 2, 2025

Summary

Add a second "Structured Response" output to the Agent component that automatically parses JSON from agent responses, giving users choice between Message and Data output types.

Key Features

  • Dual Outputs: Users can choose between "Response" (Message) and "Structured Response" (Data)
  • Clean UI: Removed conflicting json_mode toggle from Agent inputs
  • Robust JSON Parsing: Handles valid JSON, embedded JSON in text, and graceful error cases
  • Efficient Execution: Both outputs share the same agent run (no duplication)
  • Backward Compatible: Existing Agent usage continues to work unchanged

Changes Made

Agent Component (src/backend/base/langflow/components/agents/agent.py)

  • ✅ Add second output: "Structured Response" (Data type) with tool_mode=False
  • ✅ Filter json_mode from OpenAI inputs to prevent UI conflicts
  • ✅ Add json_response() method with multi-stage JSON parsing:
    • Direct JSON parsing for valid responses
    • Regex extraction for embedded JSON in text
    • Graceful error handling with diagnostic info
  • ✅ Share execution between outputs (no duplicate agent runs)
  • ✅ Fix model building to handle missing json_mode attribute

Tests (src/backend/tests/unit/components/agents/test_agent_component.py)

  • ✅ Add 9 comprehensive test cases covering:
    • Dual output structure validation
    • Input filtering verification
    • JSON parsing (valid, embedded, error cases)
    • Model building without json_mode
    • Shared execution efficiency
    • Frontend node structure
    • Component initialization

Test Plan

  • All new tests pass (9/9 test cases validated)
  • Dual outputs appear correctly in component dropdown
  • JSON parsing handles various response formats
  • No conflicts with existing OpenAI json_mode functionality
  • Model building works without AttributeError
  • Frontend node excludes json_mode from build config
  • Component initializes without errors
  • Backward compatibility maintained

Benefits

  • Better UX: Users get both Message and Data output types to choose from
  • Clean Interface: No confusing duplicate JSON toggles in UI
  • Robust Parsing: Handles various JSON response formats gracefully
  • Performance: Efficient single-execution approach
  • Compatibility: No breaking changes to existing workflows

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added support for structured JSON output in agent responses, allowing users to receive agent replies as parsed JSON when available.
  • Bug Fixes

    • Improved handling of agent inputs by filtering out unsupported fields, ensuring more accurate and reliable agent configuration.
  • Tests

    • Introduced comprehensive tests to verify correct JSON output parsing, input filtering, and consistent agent response handling.

… parsing

## Summary
- Add "Structured Response" output alongside existing "Response" output
- Filter out conflicting json_mode field from OpenAI inputs
- Implement robust JSON parsing with fallback handling

## Changes Made
### Agent Component (agent.py)
- Add second output: "Structured Response" (Data type) with tool_mode=False
- Filter json_mode from OpenAI inputs to prevent UI conflicts
- Add json_response() method with multi-stage JSON parsing:
  - Direct JSON parsing for valid responses
  - Regex extraction for embedded JSON in text
  - Graceful error handling with diagnostic info
- Share execution between outputs (no duplicate agent runs)
- Fix model building to handle missing json_mode attribute

### Tests (test_agent_component.py)
- Add 9 comprehensive test cases covering:
  - Dual output structure validation
  - Input filtering verification
  - JSON parsing (valid, embedded, error cases)
  - Model building without json_mode
  - Shared execution efficiency
  - Frontend node structure
  - Component initialization

## Benefits
- Users get both Message and Data output types to choose from
- Clean UI without confusing duplicate JSON toggles
- Robust JSON parsing handles various response formats
- Efficient single-execution approach
- Maintains backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jul 2, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

The changes add structured JSON output support to the AgentComponent class by introducing a new json_response method, refining input filtering to exclude json_mode, and updating output handling. Comprehensive asynchronous unit tests are added to verify input filtering, output structure, JSON parsing, error handling, and internal state consistency.

Changes

File(s) Change Summary
src/backend/base/langflow/components/agents/agent.py Added async json_response method, updated input/output handling, modified message_response, and improved parameter filtering.
src/backend/tests/unit/components/agents/test_agent_component.py Added extensive async unit tests covering input filtering, output structure, JSON parsing, error handling, and state sharing.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AgentComponent
    participant Agent
    User->>AgentComponent: Request structured_response
    AgentComponent->>Agent: Run agent (if not already run)
    Agent-->>AgentComponent: Return textual response
    AgentComponent->>AgentComponent: Try to parse response as JSON
    alt JSON parse succeeds
        AgentComponent-->>User: Return structured JSON Data
    else JSON parse fails
        AgentComponent->>AgentComponent: Extract JSON substring via regex
        alt Extraction succeeds
            AgentComponent-->>User: Return extracted JSON Data
        else Extraction fails
            AgentComponent-->>User: Return raw content with error message
        end
    end
Loading
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/agent-structured-output

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Jul 2, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 2, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 2, 2025
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/backend/base/langflow/components/agents/agent.py (1)

146-178: Consider supporting JSON arrays in the regex extraction.

The current implementation handles JSON parsing well, but the regex pattern r"\{.*\}" only extracts JSON objects. Consider also supporting JSON arrays:

-            json_match = re.search(r"\{.*\}", content, re.DOTALL)
+            # Try to extract JSON object or array
+            json_match = re.search(r"(\{.*\}|\[.*\])", content, re.DOTALL)
src/backend/tests/unit/components/agents/test_agent_component.py (2)

103-103: Add periods to test docstrings.

All test docstrings should end with a period according to D415:

-    async def test_agent_has_dual_outputs(self, component_class, default_kwargs):
-        """Test that Agent component has both Response and Structured Response outputs"""
+    async def test_agent_has_dual_outputs(self, component_class, default_kwargs):
+        """Test that Agent component has both Response and Structured Response outputs."""

-    async def test_json_mode_filtered_from_openai_inputs(self, component_class, default_kwargs):
-        """Test that json_mode is filtered out from OpenAI inputs"""
+    async def test_json_mode_filtered_from_openai_inputs(self, component_class, default_kwargs):
+        """Test that json_mode is filtered out from OpenAI inputs."""

-    async def test_json_response_parsing_valid_json(self, component_class, default_kwargs):
-        """Test that json_response correctly parses JSON from agent response"""
+    async def test_json_response_parsing_valid_json(self, component_class, default_kwargs):
+        """Test that json_response correctly parses JSON from agent response."""

-    async def test_json_response_parsing_embedded_json(self, component_class, default_kwargs):
-        """Test that json_response handles text containing JSON"""
+    async def test_json_response_parsing_embedded_json(self, component_class, default_kwargs):
+        """Test that json_response handles text containing JSON."""

-    async def test_json_response_error_handling(self, component_class, default_kwargs):
-        """Test that json_response handles completely non-JSON responses"""
+    async def test_json_response_error_handling(self, component_class, default_kwargs):
+        """Test that json_response handles completely non-JSON responses."""

-    async def test_model_building_without_json_mode(self, component_class, default_kwargs):
-        """Test that model building works without json_mode attribute"""
+    async def test_model_building_without_json_mode(self, component_class, default_kwargs):
+        """Test that model building works without json_mode attribute."""

-    async def test_shared_execution_between_outputs(self, component_class, default_kwargs):
-        """Test that both outputs use the same agent execution"""
+    async def test_shared_execution_between_outputs(self, component_class, default_kwargs):
+        """Test that both outputs use the same agent execution."""

-    async def test_agent_component_initialization(self, component_class, default_kwargs):
-        """Test that Agent component initializes correctly with filtered inputs"""
+    async def test_agent_component_initialization(self, component_class, default_kwargs):
+        """Test that Agent component initializes correctly with filtered inputs."""

-    async def test_frontend_node_structure(self, component_class, default_kwargs):
-        """Test that frontend node has correct structure with filtered inputs"""
+    async def test_frontend_node_structure(self, component_class, default_kwargs):
+        """Test that frontend node has correct structure with filtered inputs."""

Also applies to: 117-117, 130-130, 145-145, 160-160, 176-176, 194-194, 215-215, 225-225


114-114: Use not instead of comparing to False.

-        assert component.outputs[1].tool_mode == False
+        assert not component.outputs[1].tool_mode
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e280932 and aee9d51.

📒 Files selected for processing (2)
  • src/backend/base/langflow/components/agents/agent.py (8 hunks)
  • src/backend/tests/unit/components/agents/test_agent_component.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
`src/backend/tests/unit/components/**/*.py`: Mirror the component directory stru...

src/backend/tests/unit/components/**/*.py: Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Provide file_names_mapping in tests for backward compatibility version testing
Create comprehensive unit tests for all new components
Use the client fixture from conftest.py for FastAPI API endpoint tests
Test authenticated FastAPI endpoints using logged_in_headers in tests

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/**/*.py`: Run make format_backend to format Python code early and often Run make lint to check for linting issues in backend Python code

src/backend/**/*.py: Run make format_backend to format Python code early and often
Run make lint to check for linting issues in backend Python code

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
  • src/backend/base/langflow/components/agents/agent.py
`src/backend/tests/unit/**/*.py`: Use in-memory SQLite for database tests Test c...

src/backend/tests/unit/**/*.py: Use in-memory SQLite for database tests
Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Use pytest.mark.api_key_required and pytest.mark.no_blockbuster for tests involving external APIs

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/**/*component*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/*component*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/icons.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/**/components/**/*.py`: In your Python component class, set the `icon` attribute to a string matching the frontend icon mapping exactly (case-sensitive).

src/backend/**/components/**/*.py: In your Python component class, set the icon attribute to a string matching the frontend icon mapping exactly (case-sensitive).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/icons.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
  • src/backend/base/langflow/components/agents/agent.py
`src/backend/tests/**/*.py`: Unit tests for backend code should be located in 's...

src/backend/tests/**/*.py: Unit tests for backend code should be located in 'src/backend/tests/' and organized by component subdirectory for component tests.
Test files should use the same filename as the component with an appropriate test prefix or suffix (e.g., 'my_component.py' → 'test_my_component.py').
Use the 'client' fixture (an async httpx.AsyncClient) for API tests, as defined in 'src/backend/tests/conftest.py'.
Skip client creation in tests by marking them with '@pytest.mark.noclient' when the 'client' fixture is not needed.
Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/...

{src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py}: Each test should have a clear docstring explaining its purpose.
Complex test setups should be commented, and mock usage should be documented within the test code.
Expected behaviors should be explicitly stated in test docstrings or comments.
Create comprehensive unit tests for all new components.
Test both sync and async code paths in components.
Mock external dependencies appropriately in tests.
Test error handling and edge cases in components.
Validate input/output behavior in tests.
Test component initialization and configuration.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`{src/backend/tests/**/*.py,tests/**/*.py}`: Use '@pytest.mark.asyncio' for asyn...

{src/backend/tests/**/*.py,tests/**/*.py}: Use '@pytest.mark.asyncio' for async test functions.
Test queue operations in async tests using 'asyncio.Queue' and non-blocking put/get methods.
Use the 'no_blockbuster' pytest marker to skip the blockbuster plugin in tests.
Be aware of ContextVar propagation in async tests and test both direct event loop execution and 'asyncio.to_thread' scenarios.
Each test should ensure proper resource cleanup, especially in async fixtures using 'try/finally' and cleanup methods.
Test that operations respect timeout constraints and assert elapsed time is within tolerance.
Test Langflow's 'Message' objects and chat functionality by asserting correct properties and structure.
Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
Test components that need external APIs with proper pytest markers such as '@pytest.mark.api_key_required' and '@pytest.mark.no_blockbuster'.
Use 'MockLanguageModel' for testing language model components without external API calls.
Use 'anyio' and 'aiofiles' for async file operations in tests.
Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Test component configuration updates by asserting changes in build config dictionaries.
Test real-time event streaming endpoints by consuming NDJSON event streams and validating event structure.
Test backward compatibility across Langflow versions by mapping component files to supported versions using 'VersionComponentMapping'.
Test webhook endpoints by posting payloads and asserting correct processing and status codes.
Test error handling by monkeypatching internal functions to raise exceptions and asserting correct error responses.

📄 Source: CodeRabbit Inference Engine (.cursor/rules/testing.mdc)

List of files the instruction was applied to:

  • src/backend/tests/unit/components/agents/test_agent_component.py
`src/backend/base/langflow/components/**/*.py`: Add new backend components to th...

src/backend/base/langflow/components/**/*.py: Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/
Implement async component methods using async def and await for asynchronous operations
Use asyncio.create_task for background work in async components and ensure proper cleanup on cancellation
Use asyncio.Queue for non-blocking queue operations in async components and handle timeouts appropriately

📄 Source: CodeRabbit Inference Engine (.cursor/rules/backend_development.mdc)

List of files the instruction was applied to:

  • src/backend/base/langflow/components/agents/agent.py
🧠 Learnings (2)
src/backend/tests/unit/components/agents/test_agent_component.py (14)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Create comprehensive unit tests for all new components
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Create comprehensive unit tests for all new components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the appropriate ComponentTestBase class ('ComponentTestBase', 'ComponentTestBaseWithClient', or 'ComponentTestBaseWithoutClient') and provide the required fixtures: 'component_class', 'default_kwargs', and 'file_names_mapping' when adding a new component test.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test both sync and async code paths in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test component configuration updates by asserting changes in build config dictionaries.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Mirror the component directory structure in unit tests under src/backend/tests/unit/components/
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use ComponentTestBaseWithClient or ComponentTestBaseWithoutClient as base classes for component unit tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/**/*.py : Test component integration within flows using create_flow, build_flow, and get_build_events utilities
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Validate input/output behavior in tests.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test error handling and edge cases in components.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Test Langflow's REST API endpoints using the async 'client' fixture and assert correct status codes and response structure.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Use the client fixture from conftest.py for FastAPI API endpoint tests
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,src/frontend/**/*.test.{ts,tsx,js,jsx},src/frontend/**/*.spec.{ts,tsx,js,jsx},tests/**/*.py} : Test component initialization and configuration.
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/tests/unit/components/**/*.py : Test authenticated FastAPI endpoints using logged_in_headers in tests
src/backend/base/langflow/components/agents/agent.py (3)
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Implement async component methods using async def and await for asynchronous operations
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-06-30T14:41:58.837Z
Learning: Applies to {src/backend/tests/**/*.py,tests/**/*.py} : Use predefined JSON flows and utility functions for flow testing (e.g., 'create_flow', 'build_flow', 'get_build_events', 'consume_and_assert_stream').
Learnt from: CR
PR: langflow-ai/langflow#0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-06-30T14:39:17.428Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new backend components to the appropriate subdirectory under src/backend/base/langflow/components/
🧬 Code Graph Analysis (1)
src/backend/base/langflow/components/agents/agent.py (3)
src/backend/base/langflow/schema/data.py (1)
  • Data (23-275)
src/backend/base/langflow/template/field/base.py (1)
  • Output (181-257)
src/backend/base/langflow/base/agents/agent.py (2)
  • run_agent (120-184)
  • message_response (80-86)
🪛 GitHub Check: Ruff Style Check (3.13)
src/backend/tests/unit/components/agents/test_agent_component.py

[failure] 215-215: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:215:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 194-194: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:194:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 176-176: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:176:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 160-160: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:160:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 145-145: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:145:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 130-130: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:130:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 117-117: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:117:9: D415 First line should end with a period, question mark, or exclamation point


[failure] 114-114: Ruff (E712)
src/backend/tests/unit/components/agents/test_agent_component.py:114:16: E712 Avoid equality comparisons to False; use if not component.outputs[1].tool_mode: for false checks


[failure] 103-103: Ruff (D415)
src/backend/tests/unit/components/agents/test_agent_component.py:103:9: D415 First line should end with a period, question mark, or exclamation point

src/backend/base/langflow/components/agents/agent.py

[failure] 134-134: Ruff (TRY300)
src/backend/base/langflow/components/agents/agent.py:134:13: TRY300 Consider moving this statement to an else block

🪛 Ruff (0.11.9)
src/backend/tests/unit/components/agents/test_agent_component.py

103-103: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


114-114: Avoid equality comparisons to False; use if not component.outputs[1].tool_mode: for false checks

Replace with not component.outputs[1].tool_mode

(E712)


117-117: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


130-130: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


145-145: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


160-160: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


176-176: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


194-194: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


215-215: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)


225-225: First line should end with a period, question mark, or exclamation point

Add closing punctuation

(D415)

src/backend/base/langflow/components/agents/agent.py

134-134: Consider moving this statement to an else block

(TRY300)

🪛 Flake8 (7.2.0)
src/backend/tests/unit/components/agents/test_agent_component.py

[error] 114-114: comparison to False should be 'if cond is False:' or 'if not cond:'

(E712)

🪛 GitHub Actions: Ruff Style Check
src/backend/base/langflow/components/agents/agent.py

[error] 134-134: Ruff TRY300: Consider moving this statement to an else block.

🔇 Additional comments (6)
src/backend/base/langflow/components/agents/agent.py (5)

1-3: LGTM!

The new imports are appropriate for the JSON parsing functionality being added.

Also applies to: 24-24


46-52: Clean filtering of json_mode input.

The implementation correctly filters out the json_mode field from OpenAI inputs while preserving all other fields. This aligns with the PR objective of simplifying the UI.


91-94: Well-structured dual outputs implementation.

The outputs are properly configured with clear display names and appropriate methods. Setting tool_mode=False for the structured response is correct.


130-134: Result storage implementation is correct.

The agent result is properly stored for reuse by the json_response method. The static analysis hint about moving the return to an else block (TRY300) can be safely ignored here - the current structure is clearer since all exceptions are re-raised.


220-225: Correct handling of component parameters.

The implementation properly builds model kwargs only from existing attributes, which implicitly excludes json_mode since it was filtered from inputs.

src/backend/tests/unit/components/agents/test_agent_component.py (1)

102-238: Excellent test coverage for the new JSON output functionality.

The test suite comprehensively covers:

  • Dual output structure validation
  • Input filtering verification
  • JSON parsing scenarios (valid, embedded, error cases)
  • Model building without json_mode
  • Shared execution between outputs
  • Component initialization and frontend structure

The tests are well-structured with appropriate mocking and assertions.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 10, 2025
@ogabrielluiz ogabrielluiz added the community Pull Request from an external contributor label Jul 14, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 18, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 18, 2025
Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions github-actions Bot added the lgtm This PR has been approved by a maintainer label Jul 18, 2025
@edwinjosechittilappilly edwinjosechittilappilly added the DO NOT MERGE Don't Merge this PR label Jul 18, 2025
@github-actions github-actions Bot removed the enhancement New feature or request label Jul 18, 2025
@github-actions github-actions Bot added the enhancement New feature or request label Jul 18, 2025
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator

updating the tests!

@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator

updating tests.

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 21, 2025
@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 21, 2025
@codecov
Copy link
Copy Markdown

codecov Bot commented Jul 21, 2025

Codecov Report

Attention: Patch coverage is 75.75758% with 8 lines in your changes missing coverage. Please review.

Project coverage is 51.64%. Comparing base (16d34e0) to head (0cb37e6).
Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...c/backend/base/langflow/components/agents/agent.py 75.75% 8 Missing ⚠️

❌ Your project status has failed because the head coverage (51.64%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #8836      +/-   ##
==========================================
- Coverage   51.76%   51.64%   -0.13%     
==========================================
  Files         632      624       -8     
  Lines       43294    42913     -381     
  Branches      125        0     -125     
==========================================
- Hits        22413    22162     -251     
+ Misses      20831    20751      -80     
+ Partials       50        0      -50     
Flag Coverage Δ
backend 51.64% <75.75%> (+0.04%) ⬆️
frontend ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...kend/base/langflow/base/models/openai_constants.py 100.00% <ø> (ø)
...c/backend/base/langflow/components/agents/agent.py 59.11% <75.75%> (+7.46%) ⬆️

... and 13 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Collaborator

@edwinjosechittilappilly edwinjosechittilappilly left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@github-actions github-actions Bot added enhancement New feature or request and removed enhancement New feature or request labels Jul 21, 2025
@edwinjosechittilappilly edwinjosechittilappilly added this pull request to the merge queue Jul 21, 2025
Merged via the queue into main with commit 3bb22b2 Jul 21, 2025
70 of 71 checks passed
@edwinjosechittilappilly edwinjosechittilappilly deleted the feature/agent-structured-output branch July 21, 2025 16:52
2getsandesh pushed a commit to 2getsandesh/langflow-IBM that referenced this pull request Aug 6, 2025
… parsing (langflow-ai#8836)

* feat: Add dual output support to Agent component with structured JSON parsing

## Summary
- Add "Structured Response" output alongside existing "Response" output
- Filter out conflicting json_mode field from OpenAI inputs
- Implement robust JSON parsing with fallback handling

## Changes Made
### Agent Component (agent.py)
- Add second output: "Structured Response" (Data type) with tool_mode=False
- Filter json_mode from OpenAI inputs to prevent UI conflicts
- Add json_response() method with multi-stage JSON parsing:
  - Direct JSON parsing for valid responses
  - Regex extraction for embedded JSON in text
  - Graceful error handling with diagnostic info
- Share execution between outputs (no duplicate agent runs)
- Fix model building to handle missing json_mode attribute

### Tests (test_agent_component.py)
- Add 9 comprehensive test cases covering:
  - Dual output structure validation
  - Input filtering verification
  - JSON parsing (valid, embedded, error cases)
  - Model building without json_mode
  - Shared execution efficiency
  - Frontend node structure
  - Component initialization

## Benefits
- Users get both Message and Data output types to choose from
- Clean UI without confusing duplicate JSON toggles
- Robust JSON parsing handles various response formats
- Efficient single-execution approach
- Maintains backward compatibility

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* [autofix.ci] apply automated fixes

* update to templates with  model list update

* [autofix.ci] apply automated fixes

* Update test_agent_component.py

* update to the test and update to templates

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Edwin Jose <edwin.jose@datastax.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Pull Request from an external contributor DO NOT MERGE Don't Merge this PR enhancement New feature or request lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants