Skip to content

fix: Refactor MCP API to fix value truncation#8298

Merged
ogabrielluiz merged 9 commits into
mainfrom
fix-mcp-truncation
Jun 2, 2025
Merged

fix: Refactor MCP API to fix value truncation#8298
ogabrielluiz merged 9 commits into
mainfrom
fix-mcp-truncation

Conversation

@ogabrielluiz
Copy link
Copy Markdown
Contributor

@ogabrielluiz ogabrielluiz commented May 30, 2025

Simplify input management by replacing InputValueRequest with SimplifiedAPIRequest. Enhance flow execution clarity and performance through the use of simple_run_flow, while streamlining progress updates and message collection from flow outputs.

Summary by CodeRabbit

  • Refactor
    • Improved performance and reliability of tool calls by simplifying the flow execution process.
    • Enhanced response handling for more direct and efficient result extraction.
  • Chores
    • Removed deprecated output grouping properties from starter project configurations for cleaner metadata.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 30, 2025

"""

Walkthrough

The handle_call_tool functions in the backend API modules are refactored to use simple_run_flow for synchronous flow execution instead of the previous asynchronous streaming method. Imports and variables related to streaming and background tasks are removed. The input request type is simplified, and output extraction is performed directly from the returned result object with consolidated error handling. Progress notification handling is adjusted but preserved.

Changes

File(s) Change Summary
src/backend/base/langflow/api/v1/mcp.py Refactored handle_call_tool to use simple_run_flow synchronously, removed streaming and background logic, simplified input type and output processing, cleaned up imports and variables, and adjusted progress notification handling.
src/backend/base/langflow/api/v1/mcp_projects.py Modified ProjectMCPServer.handle_call_tool similarly to use synchronous simple_run_flow, replaced streaming and JSON parsing with direct result processing, simplified input type, refined error handling, and updated progress notification logic.
src/backend/base/langflow/initial_setup/starter_projects/*.json Removed "group_outputs" property from multiple output definitions in starter project JSON configurations without affecting logic or control flow.

Poem

In code where streams once gently flowed,
Simpler paths now ease the load.
No more tasks that run behind,
Outputs clear and easy to find.
A rabbit hops with cheerful glee—
Refactored flows, more clarity! 🐇✨
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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 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.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

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:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels May 30, 2025
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels May 30, 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: 2

🧹 Nitpick comments (1)
src/backend/base/langflow/api/v1/mcp.py (1)

260-262: Avoid spawning an unnecessary background task when progress notifications are disabled

progress_task is always created, even when enable_progress_notifications is False.
That means a task is scheduled, immediately returns, then gets cancelled – an avoidable event-loop hop.

-progress_task = asyncio.create_task(send_progress_updates())
+progress_task = None
+if mcp_config.enable_progress_notifications and server.request_context.meta.progressToken:
+    progress_task = asyncio.create_task(send_progress_updates())

Remember to guard later cancel() / await blocks with if progress_task:.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6582f06 and d4682ce.

📒 Files selected for processing (1)
  • src/backend/base/langflow/api/v1/mcp.py (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/backend/base/langflow/api/v1/mcp.py (3)
src/backend/base/langflow/api/v1/endpoints.py (1)
  • simple_run_flow (109-162)
src/backend/base/langflow/api/v1/schemas.py (1)
  • SimplifiedAPIRequest (354-363)
src/backend/base/langflow/schema/message.py (1)
  • Message (35-277)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Update Starter Projects
  • GitHub Check: Run Ruff Check and Format
  • GitHub Check: Run benchmarks (3.12)
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Ruff Style Check (3.13)

Comment thread src/backend/base/langflow/api/v1/mcp.py
Comment thread src/backend/base/langflow/api/v1/mcp.py Outdated
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels May 30, 2025
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 30, 2025

CodSpeed Performance Report

Merging #8298 will degrade performances by 14.16%

Comparing fix-mcp-truncation (87349b0) with main (7ab4951)

Summary

❌ 1 regressions
✅ 18 untouched benchmarks

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Benchmarks breakdown

Benchmark BASE HEAD Change
test_cancel_nonexistent_build 8.3 ms 9.6 ms -14.16%

@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 30, 2025
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels May 30, 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: 2

🧹 Nitpick comments (1)
src/backend/base/langflow/api/v1/mcp_projects.py (1)

322-334: Result extraction may produce unreadable output for complex types

str(value) is used as a fallback for non-Message results. For dicts, lists, or custom objects this leads to raw Python representations leaking through the API.
Consider serialising with json.dumps (for JSON-serialisable types) or adding a dedicated formatter to ensure clients always receive user-friendly text.

-else:
-    collected_results.append(types.TextContent(type="text", text=str(value)))
+else:
+    collected_results.append(
+        types.TextContent(
+            type="text",
+            text=json.dumps(value, default=str) if isinstance(value, (dict, list)) else str(value),
+        )
+    )
🧰 Tools
🪛 Pylint (3.3.7)

[convention] 326-326: Line too long (103/100)

(C0301)


[convention] 331-331: Line too long (112/100)

(C0301)


[convention] 334-334: Line too long (117/100)

(C0301)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2f643fc and 87349b0.

📒 Files selected for processing (1)
  • src/backend/base/langflow/api/v1/mcp_projects.py (3 hunks)
🧰 Additional context used
🪛 Pylint (3.3.7)
src/backend/base/langflow/api/v1/mcp_projects.py

[error] 11-11: Unable to import 'fastapi'

(E0401)


[error] 12-12: Unable to import 'fastapi.responses'

(E0401)


[error] 13-13: Unable to import 'mcp'

(E0401)


[error] 14-14: Unable to import 'mcp.server'

(E0401)


[error] 15-15: Unable to import 'mcp.server.sse'

(E0401)


[error] 16-16: Unable to import 'sqlalchemy.orm'

(E0401)


[error] 17-17: Unable to import 'sqlmodel'

(E0401)


[convention] 310-310: Line too long (115/100)

(C0301)


[convention] 326-326: Line too long (103/100)

(C0301)


[convention] 331-331: Line too long (112/100)

(C0301)


[convention] 334-334: Line too long (117/100)

(C0301)


[convention] 344-344: Line too long (112/100)

(C0301)


[warning] 335-335: Catching too general exception Exception

(W0718)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Run benchmarks (3.12)
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Starter Projects

Comment thread src/backend/base/langflow/api/v1/mcp_projects.py
Comment on lines +282 to 659
input_request = SimplifiedAPIRequest(
input_value=processed_inputs.get("input_value", ""), session_id=conversation_id
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Potential loss of user-supplied arguments – only input_value is forwarded

SimplifiedAPIRequest is instantiated with the conversation id and a single field, input_value.
All other entries contained in the incoming arguments dict (e.g. file selectors, optional parameters, model settings, etc.) are silently discarded.
Unless SimplifiedAPIRequest is intentionally restricted to one field, this breaks backward compatibility and is the most likely root-cause for “missing/empty input” bug reports.

-input_request = SimplifiedAPIRequest(
-    input_value=processed_inputs.get("input_value", ""), session_id=conversation_id
-)
+input_request = SimplifiedAPIRequest(
+    session_id=conversation_id,
+    **processed_inputs,               # keep behaviour symmetrical with the public API
+)

Please verify the target schema and forward all supported keys, or explicitly validate/raise for unsupported ones to avoid silent data loss.


🏁 Script executed:

#!/bin/bash
# Locate the definition of SimplifiedAPIRequest
rg -n "class SimplifiedAPIRequest" -A5 -B5

Length of output: 974


#!/bin/bash
# Show the full definition of SimplifiedAPIRequest including Config
sed -n '340,380p' src/backend/base/langflow/api/v1/schemas.py

#!/bin/bash
# Print the full SimplifiedAPIRequest class definition (including all fields and Config)
sed -n '340,420p' src/backend/base/langflow/api/v1/schemas.py

# Search for where processed_inputs is defined or populated in mcp_projects.py
rg -n "processed_inputs" -C5 src/backend/base/langflow/api/v1/mcp_projects.py

Forward all supported request fields to avoid silent data loss

The SimplifiedAPIRequest schema (in src/backend/base/langflow/api/v1/schemas.py) defines multiple fields beyond input_value—including input_type, output_type, output_component—and is configured with extra="forbid". In src/backend/base/langflow/api/v1/mcp_projects.py (lines 282–284), only input_value and session_id are passed, dropping everything else from processed_inputs.

• File: src/backend/base/langflow/api/v1/mcp_projects.py
Lines: ~282–284

Current code:

- input_request = SimplifiedAPIRequest(
-     input_value=processed_inputs.get("input_value", ""), 
-     session_id=conversation_id
- )

Suggested change:

- input_request = SimplifiedAPIRequest(
-     input_value=processed_inputs.get("input_value", ""), 
-     session_id=conversation_id
- )
+ input_request = SimplifiedAPIRequest(
+     session_id=conversation_id,
+     **processed_inputs,   # forwards all schema-supported keys
+ )

This ensures backward compatibility and surface validation errors for any unsupported keys.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
input_request = SimplifiedAPIRequest(
input_value=processed_inputs.get("input_value", ""), session_id=conversation_id
)
input_request = SimplifiedAPIRequest(
session_id=conversation_id,
**processed_inputs, # forwards all schema-supported keys
)
🤖 Prompt for AI Agents
In src/backend/base/langflow/api/v1/mcp_projects.py around lines 282 to 284, the
instantiation of SimplifiedAPIRequest only forwards input_value and session_id,
ignoring other supported fields from processed_inputs. To fix this, extract all
keys from processed_inputs that match the fields defined in SimplifiedAPIRequest
(such as input_type, output_type, output_component, etc.) and pass them along
with session_id when creating the SimplifiedAPIRequest instance. This will
preserve all supported user-supplied arguments and avoid silent data loss or
validation errors due to extra fields.

result = await simple_run_flow(
flow=flow,
input_request=input_request,
stream=False,
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@phact Is this a change in user-facing behavior?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

no, looks like it's a backend optimization. @ogabrielluiz is there a reason not to point build_flow_and_stream to simple_run_flow? or replace it entirely? That way other code that uses it (voice mode IIRC) gets the impovement too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I think we should remove the use of build_flow_and_stream but maybe in another PR.

The simple_run_flow takes in the flow object while build_flow_... takes the id. We could update it but one returns a response which is then iterated, while the other returns the result of the run.

text_content = types.TextContent(type="text", text=value.get_text())
collected_results.append(text_content)
else:
collected_results.append(types.TextContent(type="text", text=str(value)))
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Possible change in behavior re: collecting events by messages before results? Unsure if ordering changes or matters.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Before it was collecting events and was getting duplicated data since the last end_vertex event and the end event would have the same data.

Now it gets the result of the flow.

try:
progress_task = asyncio.create_task(send_progress_updates())
progress_task = None
if mcp_config.enable_progress_notifications and self.server.request_context.meta.progressToken:
Copy link
Copy Markdown
Collaborator

@jordanrfrazier jordanrfrazier Jun 2, 2025

Choose a reason for hiding this comment

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

leaving for seb to check - I am unfamiliar with the options here.

Comment thread src/backend/base/langflow/api/v1/mcp_projects.py
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jun 2, 2025
@edwinjosechittilappilly
Copy link
Copy Markdown
Collaborator

Quick check will Simple Run flow create or initiate a separate task/job just like build_flow_and_stream
Is so simple run flow would be better than build_flow_and_stream since it have less overhead on getting the output.

@ogabrielluiz Any other views no moving from build_flow_and_stream to simple run flow?

@ogabrielluiz
Copy link
Copy Markdown
Contributor Author

Quick check will Simple Run flow create or initiate a separate task/job just like build_flow_and_stream Is so simple run flow would be better than build_flow_and_stream since it have less overhead on getting the output.

@ogabrielluiz Any other views no moving from build_flow_and_stream to simple run flow?

we should move to simple_run_flow asap because it is the one used by the run endpoint.

- Replaced `InputValueRequest` with `SimplifiedAPIRequest` for cleaner input management.
- Updated flow execution logic to utilize `simple_run_flow`, enhancing clarity and performance.
- Removed unnecessary background task handling and streamlined progress updates.
- Improved message collection from flow outputs, ensuring robust handling of results.
- Implemented a try-except block around the flow execution to catch and handle exceptions gracefully.
- Enhanced message collection logic to ensure that errors during tool execution are communicated back as text content.
- Improved robustness of the `handle_call_tool` function by ensuring all potential errors are captured and reported.
- Updated error handling in the `handle_call_tool` function to provide more descriptive error messages.
- Changed the error message format to include the flow name, enhancing clarity for debugging purposes.
- Ensured that all exceptions during tool execution are captured and reported as text content.
- Improved the logic for processing outputs in the `handle_call_tool` function to handle messages and results more comprehensively.
- Streamlined the collection of text content from both messages and results, ensuring all relevant outputs are captured.
- Enhanced robustness by ensuring that all outputs are processed, regardless of their structure.
- Updated the logic for progress task creation in the `handle_call_tool` function to ensure it only initializes when progress notifications are enabled and a progress token is present.
- Enhanced the cancellation and exception handling of the progress task to prevent potential errors when it is not created.
- Improved overall robustness of the function by ensuring that progress updates are managed correctly based on the current context.
…PServer

- Replaced `InputValueRequest` with `SimplifiedAPIRequest` for improved input management.
- Updated flow execution to utilize `simple_run_flow`, enhancing clarity and performance.
- Refined progress notification handling to ensure tasks are only created when necessary.
- Improved message collection from flow outputs, ensuring robust handling of both messages and results.
- Enhanced error handling during tool execution to provide clearer feedback on failures.
Updated the send_progress_updates function to accept a progress token as an argument, improving its flexibility. Adjusted the task cancellation logic to use asyncio.gather for better exception handling. This change aims to streamline progress notifications when enabled.
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jun 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

♻️ Duplicate comments (2)
src/backend/base/langflow/api/v1/mcp.py (1)

235-237: Address existing input handling concerns from past reviews.

This code segment has the same issues identified in past reviews:

  1. Defaulting input_value to empty string when absent changes semantics
  2. Other supported fields like input_type, output_type, output_component, tweaks are not forwarded

The past review comment provides a comprehensive fix to preserve all supported fields and proper validation.

src/backend/base/langflow/api/v1/mcp_projects.py (1)

657-659: Same input handling issue as identified in past reviews.

This code segment has the identical issue to the one in mcp.py - only input_value and session_id are forwarded to SimplifiedAPIRequest, dropping other supported fields from processed_inputs. The past review comment provides the correct solution using **processed_inputs.

🧹 Nitpick comments (1)
src/backend/base/langflow/api/v1/mcp_projects.py (1)

679-716: Progress task management improvements but output processing concerns remain.

The refactoring successfully addresses the progress task lifecycle issues identified in past reviews:

  1. Fixed progress token scoping - Line 682 correctly passes progress_token explicitly to send_progress_updates
  2. Improved task cancellation - Line 715 uses asyncio.gather(return_exceptions=True) instead of manual exception checking

However, similar to the other file, output processing could be more robust.

Consider adding the same defensive checks as suggested for the other file:

                        result = await simple_run_flow(
                            flow=flow,
                            input_request=input_request,
                            stream=False,
                            api_key_user=current_user,
                        )
+                       # Ensure outputs exist before processing  
+                       if not result.outputs:
+                           collected_results.append(types.TextContent(type="text", text="No outputs generated from flow execution"))
+                           return collected_results
+                           
                        # Process all outputs and messages
                        for run_output in result.outputs:

This maintains consistency across both MCP implementation files.

🧰 Tools
🪛 Pylint (3.3.7)

[convention] 680-680: Line too long (115/100)

(C0301)


[convention] 698-698: Line too long (103/100)

(C0301)


[convention] 703-703: Line too long (112/100)

(C0301)


[convention] 706-706: Line too long (117/100)

(C0301)


[warning] 707-707: Catching too general exception Exception

(W0718)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fd2d02f and 1bae2c5.

📒 Files selected for processing (4)
  • src/backend/base/langflow/api/v1/mcp.py (3 hunks)
  • src/backend/base/langflow/api/v1/mcp_projects.py (3 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json (0 hunks)
  • src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json (0 hunks)
💤 Files with no reviewable changes (2)
  • src/backend/base/langflow/initial_setup/starter_projects/Youtube Analysis.json
  • src/backend/base/langflow/initial_setup/starter_projects/Research Translation Loop.json
🧰 Additional context used
🪛 Pylint (3.3.7)
src/backend/base/langflow/api/v1/mcp_projects.py

[error] 17-17: Unable to import 'fastapi'

(E0401)


[error] 18-18: Unable to import 'fastapi.responses'

(E0401)


[error] 19-19: Unable to import 'mcp'

(E0401)


[error] 20-20: Unable to import 'mcp.server'

(E0401)


[error] 21-21: Unable to import 'mcp.server.sse'

(E0401)


[error] 22-22: Unable to import 'sqlalchemy.orm'

(E0401)


[error] 23-23: Unable to import 'sqlmodel'

(E0401)


[convention] 680-680: Line too long (115/100)

(C0301)


[convention] 698-698: Line too long (103/100)

(C0301)


[convention] 703-703: Line too long (112/100)

(C0301)


[convention] 706-706: Line too long (117/100)

(C0301)


[warning] 707-707: Catching too general exception Exception

(W0718)

src/backend/base/langflow/api/v1/mcp.py

[convention] 261-261: Line too long (102/100)

(C0301)


[convention] 282-282: Line too long (104/100)

(C0301)


[convention] 285-285: Line too long (109/100)

(C0301)


[convention] 295-295: Line too long (104/100)

(C0301)


[warning] 286-286: Catching too general exception Exception

(W0718)

⏰ Context from checks skipped due to timeout of 90000ms (19)
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 6/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 8/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 7/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 1/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 10/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 5/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 4/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 9/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 3/10
  • GitHub Check: Run Frontend Tests / Playwright Tests - Shard 2/10
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 2
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 4
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 3
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Lint Backend / Run Mypy (3.13)
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Starter Projects
  • GitHub Check: Run Ruff Check and Format
🔇 Additional comments (3)
src/backend/base/langflow/api/v1/mcp.py (2)

20-21: LGTM: Import changes align with the refactoring objectives.

The new imports (simple_run_flow, SimplifiedAPIRequest, Message) are correctly added to support the transition from streaming to synchronous flow execution.

Also applies to: 24-24


260-297:

Details

✅ Verification successful

Refactoring improves synchronicity but has implementation issues.

The transition from streaming to synchronous execution using simple_run_flow aligns with the PR objectives. However, several issues need attention:

  1. Progress task management is improved - The explicit progress token parameter and proper cancellation handling address previous concerns.

  2. Output processing still has potential for data loss - Lines 273-285 process nested outputs correctly, but there's no verification that result.outputs exists or is non-empty.

Add defensive checks for the output processing:

                result = await simple_run_flow(
                    flow=flow,
                    input_request=input_request,
                    stream=False,
                    api_key_user=current_user,
                )
+               # Ensure outputs exist before processing
+               if not result.outputs:
+                   collected_results.append(types.TextContent(type="text", text="No outputs generated from flow execution"))
+                   return collected_results
+                   
                # Process all outputs and messages
                for run_output in result.outputs:
                    for component_output in run_output.outputs:

Could you verify that simple_run_flow always returns a result with an outputs attribute, even on failure?


🏁 Script executed:

#!/bin/bash
# Description: Verify the structure of result returned by simple_run_flow

# Search for the return type or structure of simple_run_flow
ast-grep --pattern 'def simple_run_flow($$$) -> $_:'
ast-grep --pattern 'async def simple_run_flow($$$) -> $_:'

# Search for result.outputs usage patterns
rg -A 3 "result\.outputs" --type py

Length of output: 1024


🏁 Script executed:

#!/bin/bash
# Locate the definition of simple_run_flow and confirm its return structure
rg -n "async def simple_run_flow" --type py
rg -n "def simple_run_flow" --type py

# List all files referencing simple_run_flow to identify its import origin
rg -l "simple_run_flow" --type py

Length of output: 572


🏁 Script executed:

#!/bin/bash
# Extract the simple_run_flow implementation to inspect its return structure
sed -n '80,300p' src/backend/base/langflow/api/v1/endpoints.py

Length of output: 8620


simple_run_flow always returns a valid outputs list, no guard needed

We verified that simple_run_flow returns a RunResponse with an outputs: list[RunOutputs] attribute on success, and on failure it raises (caught by your outer except block, which appends an error message). Therefore result.outputs is guaranteed to exist and be iterable. No additional defensive check is required to prevent missing‐attribute errors.

If you’d like to provide a user‐facing notification when the list is empty, that would be a separate UX enhancement rather than a bugfix.

🧰 Tools
🪛 Pylint (3.3.7)

[convention] 261-261: Line too long (102/100)

(C0301)


[convention] 282-282: Line too long (104/100)

(C0301)


[convention] 285-285: Line too long (109/100)

(C0301)


[convention] 295-295: Line too long (104/100)

(C0301)


[warning] 286-286: Catching too general exception Exception

(W0718)

src/backend/base/langflow/api/v1/mcp_projects.py (1)

17-17: Import changes correctly support the refactoring.

The removal of BackgroundTasks and addition of simple_run_flow, SimplifiedAPIRequest, and Message imports are consistent with the synchronous execution approach.

Also applies to: 25-25, 32-32, 35-35

🧰 Tools
🪛 Pylint (3.3.7)

[error] 17-17: Unable to import 'fastapi'

(E0401)

@ogabrielluiz ogabrielluiz enabled auto-merge June 2, 2025 21:15
@github-actions github-actions Bot added bug Something isn't working and removed bug Something isn't working labels Jun 2, 2025
@ogabrielluiz ogabrielluiz added this pull request to the merge queue Jun 2, 2025
Merged via the queue into main with commit a276c2d Jun 2, 2025
33 checks passed
@ogabrielluiz ogabrielluiz deleted the fix-mcp-truncation branch June 2, 2025 21:48
ogabrielluiz added a commit to bkatya2001/langflow that referenced this pull request Jun 24, 2025
* refactor: Simplify flow execution and update input handling in MCP API

- Replaced `InputValueRequest` with `SimplifiedAPIRequest` for cleaner input management.
- Updated flow execution logic to utilize `simple_run_flow`, enhancing clarity and performance.
- Removed unnecessary background task handling and streamlined progress updates.
- Improved message collection from flow outputs, ensuring robust handling of results.

* fix: Add error handling for tool execution in MCP API

- Implemented a try-except block around the flow execution to catch and handle exceptions gracefully.
- Enhanced message collection logic to ensure that errors during tool execution are communicated back as text content.
- Improved robustness of the `handle_call_tool` function by ensuring all potential errors are captured and reported.

* fix: Improve error messaging in tool execution for MCP API

- Updated error handling in the `handle_call_tool` function to provide more descriptive error messages.
- Changed the error message format to include the flow name, enhancing clarity for debugging purposes.
- Ensured that all exceptions during tool execution are captured and reported as text content.

* refactor: Enhance message and result handling in handle_call_tool

- Improved the logic for processing outputs in the `handle_call_tool` function to handle messages and results more comprehensively.
- Streamlined the collection of text content from both messages and results, ensuring all relevant outputs are captured.
- Enhanced robustness by ensuring that all outputs are processed, regardless of their structure.

* refactor: Improve progress notification handling in handle_call_tool

- Updated the logic for progress task creation in the `handle_call_tool` function to ensure it only initializes when progress notifications are enabled and a progress token is present.
- Enhanced the cancellation and exception handling of the progress task to prevent potential errors when it is not created.
- Improved overall robustness of the function by ensuring that progress updates are managed correctly based on the current context.

* refactor: Streamline flow execution and message handling in ProjectMCPServer

- Replaced `InputValueRequest` with `SimplifiedAPIRequest` for improved input management.
- Updated flow execution to utilize `simple_run_flow`, enhancing clarity and performance.
- Refined progress notification handling to ensure tasks are only created when necessary.
- Improved message collection from flow outputs, ensuring robust handling of both messages and results.
- Enhanced error handling during tool execution to provide clearer feedback on failures.

* refactor: enhance progress update handling in ProjectMCPServer

Updated the send_progress_updates function to accept a progress token as an argument, improving its flexibility. Adjusted the task cancellation logic to use asyncio.gather for better exception handling. This change aims to streamline progress notifications when enabled.

* refactor: add group_outputs property to message configurations in starter projects
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working 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.

4 participants