Skip to content

Conversation

@HzaRashid
Copy link
Collaborator

@HzaRashid HzaRashid commented Nov 25, 2025

from #10576 (moved from fork to langflow-ai)

This PR implements various improvements and optimizations (Breaking Changes) for the run flow component.

  • Given the scope and complexity of this PR, the reviewer is encouraged to checkout its branch and test run_flow's behavior manually.

This PR implements the following improvements to the runflow component:

  1. Flow Selection: Filter only the flows available in the specific project.
  2. Sorted: Sort from most recent flow edited.
  3. Sync Flows: Add a refresh button to re-fetch the flows.
  4. Output Structure: Outputs appear dynamically after loading the flow.
  5. Field-naming: Improved user-friendliness of field naming for inputs and outputs, with simple defaults that gain specificity upon duplicate components and input/output field name conflicts (by adding the component name or id when needed).
  6. Implemented database queries for fetching flows per folder and fetching a particular flow by flow id or name. The previous code would fetch all flows and later filter the result to select the user-selected one, which is very inefficient.
  7. Added fields to the frontend node field config that is sent to the backend in order to optimize backend behavior; e.g., an explicit 'refresh' flag for when the refresh button is clicked (otherwise, on each click of a dropdown item, the entire list data is re-fetched from the database, which is very expensive. This problem is not exclusive to the run flow component, every component's update_build_config is run each time a dropdown item is selected).
  8. Utilize the cache service to store the selected flow in memory, to avoid further database querying. We note that the component falls back to using the db when the cache service it not available. Further, this caching feature is optional.
  9. Implements cache invalidation for the optional cache feature via last edited dates of flows.
  10. Run outputs are cached (only for that run, and set to None in _pre_run_setup to start with a fresh slate) to avoid re-executing the selected flow for each of its outputs that needs to be resolved.
  11. Added a override_skip boolean flag to the base input mixin so that derived inputs (e.g., the id of the selected flow) can be persisted to runtime but kept hidden from the user entirely (show=False) for user-friendliness.
  12. Added unit and integration tests.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 25, 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

This PR adds flow retrieval and caching capabilities across backend and frontend. It introduces new helpers for listing flows by folder context, flow-based retrieval, and implements comprehensive caching and dynamic output resolution in RunFlowBaseComponent. Frontend updates propagate metadata and refresh signals through the UI. Integration and unit tests validate the new functionality.

Changes

Cohort / File(s) Summary
Flow Retrieval Helpers
src/backend/base/langflow/helpers/flow.py, src/lfx/src/lfx/helpers/flow.py, src/lfx/src/lfx/helpers/__init__.py
Adds three new async flow helper functions: list_flows_by_flow_folder, list_flows_by_folder_id, and get_flow_by_id_or_name with input validation. Backend version queries database; LFX version provides stubs with warnings. Both exposed via public exports.
Flow Model Enhancement
src/backend/base/langflow/services/database/models/flow/model.py
Updates Flow.to_data() to include folder_id in serialized output.
RunFlowBaseComponent - Caching & Outputs
src/lfx/src/lfx/base/tools/run_flow.py
Comprehensive refactor introducing flow graph caching with staleness checks, dynamic output resolution, flow-by-id/name retrieval, tool integration, input/tweak extraction, and pre-run setup. Adds 20+ new methods for graph caching, output formatting, and flow execution.
RunFlowComponent - Build Config Updates
src/lfx/src/lfx/components/flow_controls/run_flow.py
Refactors update_build_config to pre-populate keys, handle flow selection with metadata derivation, load graphs, and check for stale flows. Adds helper methods: get_selected_flow_meta, load_graph_and_update_cfg, should_update_stale_flow, check_and_update_stale_flow, get_str_isots.
CustomComponent - Flow Listing
src/lfx/src/lfx/custom/custom_component/custom_component.py
Expands flow helper imports and adds three async methods: alist_flows_by_flow_folder, alist_flows_by_folder_id, aget_flow_by_id_or_name using runtime/frontend attributes for context.
Chat Session ID Handling
src/lfx/src/lfx/components/input_output/chat.py, src/lfx/src/lfx/components/input_output/chat_output.py
Updates session ID assignment to fallback gracefully to graph's session_id when not explicitly provided.
Component Update Outputs - Async Support
src/lfx/src/lfx/custom/custom_component/component.py
Modifies run_and_validate_update_outputs to detect and await coroutine functions from update_outputs.
Field Skip Override
src/lfx/src/lfx/graph/vertex/param_handler.py, src/lfx/src/lfx/inputs/input_mixin.py
Adds override_skip boolean field to BaseInputMixin (default False); param_handler respects it to force field processing.
Frontend - Template Mutation & Refresh
src/frontend/src/CustomNodes/helpers/mutate-template.ts, src/frontend/src/components/core/dropdownComponent/index.tsx, src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx
Adds isRefresh parameter to mutateTemplate, threaded through debounced calls as is_refresh in API payload. Dropdown components now pass isRefresh: true on refresh and handle selectedMetadata.
Frontend - Query & Types
src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts, src/frontend/src/types/components/index.ts
Augments template with _frontend_node_flow_id, _frontend_node_folder_id, and is_refresh from flows manager store. Extends DropDownComponent.onSelect signature with optional selectedMetadata parameter.
Backend - Flow Helper Tests
src/backend/tests/unit/helpers/test_flow_helpers.py
Unit tests for backend flow helpers validating error conditions (missing user_id/ids), database query paths with Data wrapping, and ordering parameter handling.
Backend - RunFlow Integration Tests
src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
Comprehensive integration test suite for RunFlow covering end-to-end flow creation, execution, tool generation, output resolution, caching behavior, and cleanup.
Backend - RunFlow Unit Tests
src/backend/tests/unit/base/tools/test_run_flow.py
Extensive unit tests for RunFlowBaseComponent covering initialization, flow retrieval, graph caching, cache operations, I/O handling, pre-run setup, output resolution, and tool generation.
Backend - RunFlowComponent Unit Tests
src/backend/tests/unit/components/logic/test_run_flow_component.py
Unit tests for RunFlowComponent covering initialization metadata, helper methods, async workflows (graph loading, staleness checks), build config updates with various scenarios, and runtime execution.
LFX - Flow Helper Tests
src/lfx/tests/unit/helpers/test_flow_helpers.py
Unit tests for LFX flow helpers validating input extraction, schema building, arg name mapping, flow listing error handling, and run_flow input construction.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant UI as Frontend UI
    participant Template as mutateTemplate
    participant API as API Call
    participant Backend as Backend Services
    participant DB as Database
    
    User->>UI: Select flow / trigger refresh
    UI->>Template: mutateTemplate(..., isRefresh=true)
    Template->>API: POST with is_refresh=true in payload
    
    alt is_refresh = true
        API->>Backend: list_flows_by_flow_folder()
        Backend->>DB: Query flows in same folder
        DB-->>Backend: Flow list with updated_at
        Backend->>Backend: Sort by order_params
        Backend-->>API: Return flows + metadata
        API-->>UI: Update dropdown options
    else is_refresh = false
        API->>Backend: get_flow_by_id_or_name()
        Backend->>Backend: Load graph + derive outputs
        Backend-->>API: Flow data + graph structure
        API-->>UI: Update build config
    end
    
    UI->>User: Reflect changes (options/config)
Loading
sequenceDiagram
    participant RunFlow as RunFlowComponent
    participant Cache as Flow Cache
    participant DB as Database
    participant Graph as Graph Builder
    
    RunFlow->>RunFlow: update_build_config()
    
    alt Flow selection changes
        RunFlow->>RunFlow: get_selected_flow_meta()
        RunFlow->>DB: Fetch flow by derived flow_id
        RunFlow->>RunFlow: load_graph_and_update_cfg()
        RunFlow->>Graph: Reconstruct graph from payload
        Graph-->>RunFlow: Graph object
        RunFlow->>RunFlow: update_build_config_from_graph()
        RunFlow->>RunFlow: Delete old output fields
    else Refresh triggered (is_refresh=true)
        RunFlow->>DB: list_flows_by_flow_folder()
        DB-->>RunFlow: Available flows list
        RunFlow->>RunFlow: Populate flow_name_selected.options
        RunFlow->>RunFlow: check_and_update_stale_flow()
        
        alt Flow is stale
            RunFlow->>RunFlow: load_graph_and_update_cfg()
            RunFlow->>Graph: Reload graph
            Graph-->>RunFlow: Updated graph
        end
    end
    
    RunFlow->>RunFlow: Sync to frontend
Loading
sequenceDiagram
    participant Runner as Flow Runner
    participant RFComp as RunFlowBaseComponent
    participant Cache as Cache Service
    participant GraphMgr as Graph Manager
    
    Runner->>RFComp: _run_flow_with_cached_graph()
    RFComp->>RFComp: _build_flow_cache_key()
    RFComp->>Cache: _get_cached_flow()
    
    alt Cache Hit & Up-to-date
        Cache-->>RFComp: Cached Graph
        RFComp->>RFComp: _is_cached_flow_up_to_date()
        rect rgb(144, 238, 144)
            Note over RFComp,Cache: Use cached graph
            RFComp->>RFComp: _pre_run_setup()
        end
    else Cache Miss or Stale
        RFComp->>GraphMgr: get_graph()
        GraphMgr-->>RFComp: Fresh Graph
        RFComp->>Cache: _set_cached_flow()
        Cache-->>RFComp: Cached
    end
    
    RFComp->>RFComp: _build_inputs_from_tweaks()
    RFComp->>RFComp: run_flow(graph, inputs)
    RFComp->>RFComp: _get_cached_run_outputs()
    RFComp-->>Runner: Results
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • src/lfx/src/lfx/base/tools/run_flow.py — Large refactor with 20+ new methods covering caching logic, dynamic output resolution, cache invalidation, and graph reconstruction. Critical logic for timestamp comparison, cache key generation, and stale detection needs careful review.
  • src/lfx/src/lfx/components/flow_controls/run_flow.py — Complex state management in update_build_config with multiple branching paths for flow selection, refresh, staleness checks, and metadata derivation. Risk of incorrect flow_id derivation or stale cache retention.
  • Backend test suites (test_run_flow.py, test_run_flow_component.py, test_run_flow_integration.py) — High-complexity tests with extensive mocking and async workflows; validate correctness of caching, metadata propagation, and graph reloading under various scenarios.
  • Frontend flow context threading — Multiple files modified to thread flow_id, folder_id, and is_refresh through API calls; verify payload construction consistency across dropdown, template mutation, and query layers.
  • Database query logic in flow helperslist_flows_by_flow_folder and related queries involve SQL aliasing and sorting dispatcher; verify correct folder filtering and ordering parameter application.

Possibly related PRs

Suggested labels

enhancement, flow-controls, caching, backend, frontend, testing

Suggested reviewers

  • edwinjosechittilappilly
  • ogabrielluiz
  • jordanrfrazier

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Test Quality And Coverage ⚠️ Warning Async tests lack @pytest.mark.asyncio decorators, tests average only 1.9 assertions per function, and critical functionality (cache operations, graph construction, stale detection) lacks adequate coverage. Add @pytest.mark.asyncio to all async tests, increase assertion depth per test to validate actual behavior not just mock responses, and expand error scenario coverage for edge cases and failure paths.
Test File Naming And Structure ⚠️ Warning Test files show proper naming conventions and pytest structure, but contain 152+ duplicate lines in backend_unit_test.py, 182+ in backend_component_test.py, and 40+ in integration_test.py. Frontend components modified without corresponding tests. Remove all duplicate lines from affected test files and add corresponding Playwright or Jest tests for modified frontend components (mutate-template.ts, dropdownComponent, parameterRenderComponent, use-post-template-value.ts).
Excessive Mock Usage Warning ⚠️ Warning Pull request contains excessive mock usage in unit tests with high mock-to-test ratios (4.4 in test_flow_helpers.py, 0.9 in test_run_flow.py), mocking core business logic instead of testing actual behavior, reducing test maintainability and reliability. Reduce mock instances through shared fixtures, replace core business logic mocks with real objects, test public APIs, and move complex verification to integration tests using in-memory database.
✅ Passed checks (4 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 80.68% which is sufficient. The required threshold is 80.00%.
Test Coverage For New Implementations ✅ Passed PR includes comprehensive test coverage across five test files with 106 total test methods. Backend tests include proper mocking of database interactions and error handling. Integration tests provide end-to-end workflow testing. Tests follow project naming conventions and use proper testing patterns.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately reflects the main changes: introducing RunFlow optimization (caching, dynamic outputs, graph handling) and improved dropdown behavior (metadata filtering, refresh handling).

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Nov 25, 2025

Frontend Unit Test Coverage Report

Coverage Summary

Lines Statements Branches Functions
Coverage: 15%
15.29% (4188/27381) 8.49% (1778/20935) 9.6% (579/6031)

Unit Test Results

Tests Skipped Failures Errors Time
1638 0 💤 0 ❌ 0 🔥 20.032s ⏱️

@codecov
Copy link

codecov bot commented Nov 25, 2025

Codecov Report

❌ Patch coverage is 24.17062% with 320 lines in your changes missing coverage. Please review.
✅ Project coverage is 32.48%. Comparing base (3caacf4) to head (40ae0c8).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/lfx/src/lfx/base/tools/run_flow.py 0.00% 253 Missing ⚠️
...rc/lfx/custom/custom_component/custom_component.py 13.51% 32 Missing ⚠️
src/backend/base/langflow/helpers/flow.py 85.89% 11 Missing ⚠️
...llers/API/queries/nodes/use-post-template-value.ts 0.00% 7 Missing ⚠️
...nd/src/components/core/dropdownComponent/index.tsx 0.00% 5 Missing ⚠️
...erComponent/components/dropdownComponent/index.tsx 0.00% 5 Missing ⚠️
...rontend/src/CustomNodes/helpers/mutate-template.ts 0.00% 3 Missing ⚠️
...c/lfx/src/lfx/custom/custom_component/component.py 33.33% 1 Missing and 1 partial ⚠️
src/lfx/src/lfx/graph/vertex/param_handler.py 0.00% 1 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (24.17%) is below the target coverage (40.00%). You can increase the patch coverage or adjust the target coverage.
❌ Your project status has failed because the head coverage (40.08%) 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   #10720      +/-   ##
==========================================
+ Coverage   32.40%   32.48%   +0.08%     
==========================================
  Files        1366     1366              
  Lines       62953    63294     +341     
  Branches     9305     9356      +51     
==========================================
+ Hits        20401    20564     +163     
- Misses      41524    41698     +174     
- Partials     1028     1032       +4     
Flag Coverage Δ
backend 51.39% <85.89%> (+0.31%) ⬆️
frontend 14.13% <0.00%> (-0.01%) ⬇️
lfx 40.08% <10.80%> (-0.14%) ⬇️

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

Files with missing lines Coverage Δ
...se/langflow/services/database/models/flow/model.py 76.66% <ø> (ø)
src/lfx/src/lfx/helpers/flow.py 95.12% <100.00%> (+73.30%) ⬆️
src/lfx/src/lfx/inputs/input_mixin.py 82.83% <100.00%> (+0.14%) ⬆️
...c/lfx/src/lfx/custom/custom_component/component.py 58.45% <33.33%> (-0.13%) ⬇️
src/lfx/src/lfx/graph/vertex/param_handler.py 84.32% <0.00%> (-0.93%) ⬇️
...rontend/src/CustomNodes/helpers/mutate-template.ts 0.00% <0.00%> (ø)
...nd/src/components/core/dropdownComponent/index.tsx 0.00% <0.00%> (ø)
...erComponent/components/dropdownComponent/index.tsx 0.00% <0.00%> (ø)
...llers/API/queries/nodes/use-post-template-value.ts 0.00% <0.00%> (ø)
src/backend/base/langflow/helpers/flow.py 46.55% <85.89%> (+20.74%) ⬆️
... and 2 more

... and 4 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
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: 9

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/lfx/src/lfx/components/input_output/chat_output.py (1)

130-139: Critical: Inconsistent session_id usage breaks message storage.

Line 130 derives a session_id by falling back to self.graph.session_id, but line 136 still checks self.session_id for the storage condition. This creates a bug where:

  • If self.session_id is empty but self.graph.session_id has a value, the message will be assigned a session_id but won't be stored.

This is inconsistent with the correct implementation in chat.py (lines 92-101), which derives the session_id into a variable and uses it consistently.

Apply this diff to fix the inconsistency:

+        session_id = self.session_id or self.graph.session_id or ""
         message.sender = self.sender
         message.sender_name = self.sender_name
-        message.session_id = self.session_id or self.graph.session_id or ""
+        message.session_id = session_id
         message.context_id = self.context_id
         message.flow_id = self.graph.flow_id if hasattr(self, "graph") else None
         message.properties.source = self._build_source(source_id, display_name, source)
 
         # Store message if needed
-        if self.session_id and self.should_store_message:
+        if session_id and self.should_store_message:
             stored_message = await self.send_message(message)
             self.message.value = stored_message
             message = stored_message
src/lfx/src/lfx/base/tools/run_flow.py (1)

282-297: Unpacking failure when get_required_data returns None.

If get_required_data returns None (as its type hint indicates it can), the tuple unpacking on line 285 will raise TypeError: cannot unpack non-iterable NoneType object.

Apply this diff to handle the None case:

     async def _get_tools(self) -> list[Tool]:
         """Expose flow as a tool."""
         component_toolkit: type[ComponentToolkit] = get_component_toolkit()
-        flow_description, tool_mode_inputs = await self.get_required_data()
+        result = await self.get_required_data()
+        if result is None:
+            return []
+        flow_description, tool_mode_inputs = result
         if not tool_mode_inputs:
             return []
🧹 Nitpick comments (13)
src/backend/tests/unit/base/tools/test_run_flow.py (2)

1-11: Remove unused import.

Message is imported but never used in the test file.

 from unittest.mock import AsyncMock, MagicMock, Mock, PropertyMock, patch
 from uuid import uuid4
 
 import pytest
 from lfx.base.tools.run_flow import RunFlowBaseComponent
 from lfx.graph.graph.base import Graph
 from lfx.schema.data import Data
 from lfx.schema.dotdict import dotdict
 from lfx.services.cache.utils import CacheMiss
 from lfx.template.field.base import Output
-

463-481: Test relies on hardcoded separator value.

The test uses ~ as the separator directly. Consider using component.IOPUT_SEP to ensure the test stays in sync if the separator constant changes.

     def test_extract_tweaks_from_keyed_values(self):
         """Test extracting tweaks from keyed values."""
         component = RunFlowBaseComponent()
+        sep = component.IOPUT_SEP
 
         values = {
-            "vertex1~param1": "value1",
-            "vertex1~param2": "value2",
-            "vertex2~param1": "value3",
+            f"vertex1{sep}param1": "value1",
+            f"vertex1{sep}param2": "value2",
+            f"vertex2{sep}param1": "value3",
             "invalid_key": "should_be_ignored",
         }
src/lfx/src/lfx/helpers/flow.py (1)

88-93: Mutable default argument pattern.

The order_params parameter uses a mutable dict as default. While the # noqa: B006 suppresses the lint warning, this is still a potential gotcha if the function ever modifies the dict. Since this is a stub that doesn't use order_params, it's low risk, but consider using None with a fallback for consistency with defensive coding practices.

 async def list_flows_by_flow_folder(
     *,
     user_id: str | None = None,
     flow_id: str | None = None,
-    order_params: dict | None = {"column": "updated_at", "direction": "desc"} # noqa: B006, ARG001
+    order_params: dict | None = None,  # noqa: ARG001
     ) -> list[Data]:
src/backend/base/langflow/helpers/flow.py (2)

51-56: Mutable default argument for order_params.

Same pattern as the lfx stub - using a mutable dict as default. While the current implementation doesn't mutate the dict, consider using None with a fallback for defensive coding.

 async def list_flows_by_flow_folder(
     *,
     user_id: str | None = None,
     flow_id: str | None = None,
-    order_params: dict | None = {"column": "updated_at", "direction": "desc"} # noqa: B006
+    order_params: dict | None = None,
     ) -> list[Data]:
+    if order_params is None:
+        order_params = {"column": "updated_at", "direction": "desc"}

136-147: Redundant validation after already checking flow_id or flow_name.

Lines 145-147 check if not (attr and val) and raise an error, but this condition is unreachable. The earlier check on line 132-134 ensures either flow_id or flow_name is provided, and lines 139-144 guarantee attr and val are set from one of them.

     # set user provided flow id or flow name.
     # if both are provided, flow_id is used.
     attr, val = None, None
     if flow_name:
         attr = "name"
         val = flow_name
     if flow_id:
         attr = "id"
         val = flow_id
-    if not (attr and val):
-        msg = "Flow id or Name is required"
-        raise ValueError(msg)
src/backend/tests/unit/helpers/test_flow_helpers.py (1)

214-240: Consider strengthening the "prefers id over name" assertion.

The test verifies that exec was called once but doesn't verify that the query used the id attribute instead of name. To fully validate this behavior, you could capture and inspect the SQL statement or verify the mock was called with specific arguments.

Example enhancement:

# Capture the select statement from the exec call
call_args = mock_session.exec.call_args
select_stmt = call_args[0][0]
# Verify the where clause uses Flow.id, not Flow.name
# (This would require more sophisticated inspection of the SQLAlchemy statement)
src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py (1)

303-305: Minor inconsistency: model_dump() vs model_dump(mode="json").

Line 304 uses flow.model_dump() while other similar calls in this file (e.g., lines 40, 56, 168, 184, 246) use model_dump(mode="json"). This inconsistency could lead to different serialization behavior if the flow contains non-JSON-serializable types like datetime objects.

-        response = await client.post("api/v1/flows/", json=flow.model_dump(), headers=logged_in_headers)
+        response = await client.post("api/v1/flows/", json=flow.model_dump(mode="json"), headers=logged_in_headers)
src/lfx/src/lfx/components/flow_controls/run_flow.py (2)

47-48: Prefer parentheses over backslash for line continuation.

Line continuation using backslash is less preferred in Python. Using parentheses is cleaner and more robust.

-                build_config["flow_name_selected"]["options_metadata"] \
-                    .append({"id": flow.data["id"], "updated_at": flow.data["updated_at"]})
+                build_config["flow_name_selected"]["options_metadata"].append(
+                    {"id": flow.data["id"], "updated_at": flow.data["updated_at"]}
+                )

73-75: Return type annotation mismatch.

The method returns build_config.get(...).get(...).get(field) which can return None at any step, but the return type is annotated as dict. Should be -> Any or -> dict | None.

-    def get_selected_flow_meta(self, build_config: dotdict, field: str) -> dict:
+    def get_selected_flow_meta(self, build_config: dotdict, field: str) -> Any:
src/lfx/src/lfx/base/tools/run_flow.py (1)

612-616: Dead code: or 'missing_id' is unreachable.

Line 614 raises a ValueError when flow_id is falsy, so the or 'missing_id' fallback on line 616 can never execute. Consider removing it for clarity.

     def _build_flow_cache_key(self, *, flow_id: str | None = None) -> str | None:
         if not (self.user_id and flow_id):
             msg = "Failed to build cache key: Flow ID and user ID are required"
             raise ValueError(msg)
-        return f"run_flow:{self.user_id}:{flow_id or 'missing_id'}"
+        return f"run_flow:{self.user_id}:{flow_id}"
src/frontend/src/components/core/dropdownComponent/index.tsx (2)

115-122: Centralize metadata key filtering to avoid future drift

You now exclude id/updated_at in both filterMetadataKeys and formatTooltipContent. To keep behavior in sync long‑term, consider reusing filterMetadataKeys inside formatTooltipContent (and adjusting its excludeKeys list if needed) instead of duplicating the exclusion logic in two places.

Also applies to: 285-302, 540-568


263-283: Refresh handling and metadata passing are wired correctly

  • handleRefreshButtonPress correctly calls mutateTemplate with isRefresh = true, matching the updated helper and API payload shape.
  • In the options list, onSelect(currentValue, undefined, undefined, filteredMetadata?.[index]) cleanly passes the selected option’s metadata downstream while preserving existing argument order.

One behavioral note: refreshOptions is reset via a fixed timeout rather than awaiting the debounced mutation’s completion, so the loading state is time‑based rather than tied to request success. If you want the spinner to reflect actual completion, you’d need to hook into the mutation state instead of using a hardcoded delay.

Also applies to: 487-504

src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts (1)

11-23: Confirm backend contract for is_refresh and template augmentation

  • Injecting _frontend_node_flow_id / _frontend_node_folder_id as { value: id } fields on the template looks consistent with existing field shapes.
  • is_refresh is added as a plain boolean on the template (is_refresh: payload.is_refresh), unlike the other injected fields. Please confirm the backend either explicitly expects this raw boolean or safely ignores non‑field entries on the template object so this doesn’t break template processing.
  • Minor nit: you call useFlowsManagerStore twice; you could destructure currentFlowId and currentFlow in a single selector and derive folderId from that to avoid duplicate subscriptions.

Also applies to: 39-53, 55-63

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8b67a37 and 5eba59f.

📒 Files selected for processing (22)
  • src/backend/base/langflow/helpers/flow.py (3 hunks)
  • src/backend/base/langflow/services/database/models/flow/model.py (1 hunks)
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py (1 hunks)
  • src/backend/tests/unit/base/tools/test_run_flow.py (1 hunks)
  • src/backend/tests/unit/components/logic/test_run_flow_component.py (1 hunks)
  • src/backend/tests/unit/helpers/test_flow_helpers.py (1 hunks)
  • src/frontend/src/CustomNodes/helpers/mutate-template.ts (3 hunks)
  • src/frontend/src/components/core/dropdownComponent/index.tsx (4 hunks)
  • src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx (1 hunks)
  • src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts (2 hunks)
  • src/frontend/src/types/components/index.ts (1 hunks)
  • src/lfx/src/lfx/base/tools/run_flow.py (3 hunks)
  • src/lfx/src/lfx/components/flow_controls/run_flow.py (2 hunks)
  • src/lfx/src/lfx/components/input_output/chat.py (1 hunks)
  • src/lfx/src/lfx/components/input_output/chat_output.py (1 hunks)
  • src/lfx/src/lfx/custom/custom_component/component.py (1 hunks)
  • src/lfx/src/lfx/custom/custom_component/custom_component.py (3 hunks)
  • src/lfx/src/lfx/graph/vertex/param_handler.py (1 hunks)
  • src/lfx/src/lfx/helpers/__init__.py (4 hunks)
  • src/lfx/src/lfx/helpers/flow.py (1 hunks)
  • src/lfx/src/lfx/inputs/input_mixin.py (1 hunks)
  • src/lfx/tests/unit/helpers/test_flow_helpers.py (1 hunks)
🧰 Additional context used
📓 Path-based instructions (10)
src/frontend/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{ts,tsx}: Use React 18 with TypeScript for frontend development
Use Zustand for state management

Files:

  • src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx
  • src/frontend/src/components/core/dropdownComponent/index.tsx
  • src/frontend/src/types/components/index.ts
  • src/frontend/src/CustomNodes/helpers/mutate-template.ts
  • src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts
src/frontend/src/**/*.{tsx,jsx,css,scss}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

Use Tailwind CSS for styling

Files:

  • src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx
  • src/frontend/src/components/core/dropdownComponent/index.tsx
src/frontend/src/components/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/components/**/*.{tsx,jsx}: Use React Flow for flow graph visualization with Node, Edge, Controls, and Background components
Use the cn() utility function for combining Tailwind CSS classes in components
Use TypeScript interfaces for defining component props in React components

Files:

  • src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx
  • src/frontend/src/components/core/dropdownComponent/index.tsx
src/frontend/src/**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/frontend_development.mdc)

src/frontend/src/**/*.{tsx,jsx}: Implement dark mode support using the useDarkMode hook and dark store
Use Lucide React for icon components in the application

Files:

  • src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx
  • src/frontend/src/components/core/dropdownComponent/index.tsx
src/backend/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

src/backend/**/*.py: Use FastAPI async patterns with await for async operations in component execution methods
Use asyncio.create_task() for background tasks and implement proper cleanup with try/except for asyncio.CancelledError
Use queue.put_nowait() for non-blocking queue operations and asyncio.wait_for() with timeouts for controlled get operations

Files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/backend/base/langflow/services/database/models/flow/model.py
  • src/backend/base/langflow/helpers/flow.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
src/backend/tests/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/testing.mdc)

src/backend/tests/**/*.py: Place backend unit tests in src/backend/tests/ directory, component tests in src/backend/tests/unit/components/ organized by component subdirectory, and integration tests accessible via make integration_tests
Use same filename as component with appropriate test prefix/suffix (e.g., my_component.pytest_my_component.py)
Use the client fixture (FastAPI Test Client) defined in src/backend/tests/conftest.py for API tests; it provides an async httpx.AsyncClient with automatic in-memory SQLite database and mocked environment variables. Skip client creation by marking test with @pytest.mark.noclient
Inherit from the correct ComponentTestBase family class located in src/backend/tests/base.py based on API access needs: ComponentTestBase (no API), ComponentTestBaseWithClient (needs API), or ComponentTestBaseWithoutClient (pure logic). Provide three required fixtures: component_class, default_kwargs, and file_names_mapping
Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes
Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration
Use @pytest.mark.asyncio decorator for async component tests and ensure async methods are properly awaited
Test background tasks using asyncio.create_task() and verify completion with asyncio.wait_for() with appropriate timeout constraints
Test queue operations using non-blocking queue.put_nowait() and asyncio.wait_for(queue.get(), timeout=...) to verify queue processing without blocking
Use @pytest.mark.no_blockbuster marker to skip the blockbuster plugin in specific tests
For database tests that may fail in batch runs, run them sequentially using uv run pytest src/backend/tests/unit/test_database.py r...

Files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
**/{test_*.py,*.test.ts,*.test.tsx}

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

Check that test files follow the project's naming conventions (test_*.py for backend, *.test.ts for frontend)

Files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
**/test_*.py

📄 CodeRabbit inference engine (coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt)

**/test_*.py: Backend tests should follow pytest structure with proper test_*.py naming
For async functions, ensure proper async testing patterns are used with pytest for backend

Files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
src/backend/base/langflow/services/database/models/**/*.py

📄 CodeRabbit inference engine (.cursor/rules/backend_development.mdc)

Database models should be organized by domain (api_key/, flow/, folder/, user/, etc.) under src/backend/base/langflow/services/database/models/

Files:

  • src/backend/base/langflow/services/database/models/flow/model.py
src/backend/**/*component*.py

📄 CodeRabbit inference engine (.cursor/rules/icons.mdc)

In Python component classes, set the icon attribute to a string matching the desired icon name (e.g., icon = "AstraDB"). The string must match the frontend icon mapping exactly (case-sensitive).

Files:

  • src/backend/tests/unit/components/logic/test_run_flow_component.py
🧠 Learnings (22)
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Use predefined JSON flows and utility functions from `tests.unit.build_utils` (create_flow, build_flow, get_build_events, consume_and_assert_stream) for flow execution testing

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/src/lfx/components/flow_controls/run_flow.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/src/lfx/helpers/__init__.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/lfx/src/lfx/helpers/flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to tests/unit/**/*.py : Database and flow integration tests should use helper functions from `tests.unit.build_utils` such as `create_flow`, `build_flow`, and `get_build_events`

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/src/lfx/components/flow_controls/run_flow.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/lfx/src/lfx/helpers/flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Test both sync and async code paths, mock external dependencies appropriately, test error handling and edge cases, validate input/output behavior, and test component initialization and configuration

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Create comprehensive unit tests for all new backend components. If unit tests are incomplete, create a corresponding Markdown file documenting manual testing steps and expected outcomes

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Use `monkeypatch` fixture to mock internal functions for testing error handling scenarios; validate error status codes and error message content in responses

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow REST API endpoints using the `client` fixture with appropriate HTTP methods (GET, POST, etc.), headers (logged_in_headers), and payload validation

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Place backend unit tests in `src/backend/tests/` directory, component tests in `src/backend/tests/unit/components/` organized by component subdirectory, and integration tests accessible via `make integration_tests`

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Use `aiofiles` and `anyio.Path` for async file operations in tests; create temporary test files using `tmp_path` fixture and verify file existence and content

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Test component versioning and backward compatibility using `file_names_mapping` fixture with `VersionComponentMapping` objects mapping component files across Langflow versions

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Test Langflow's `Message` objects using `langflow.schema.message.Message` and validate text, sender, sender_name, session_id, files, and properties attributes

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
  • src/lfx/tests/unit/helpers/test_flow_helpers.py
📚 Learning: 2025-11-24T19:47:40.371Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: coderabbit-custom-pre-merge-checks-unique-id-file-non-traceable-F7F2B60C-1728-4C9A-8889-4F2235E186CA.txt:0-0
Timestamp: 2025-11-24T19:47:40.371Z
Learning: Applies to **/test_*.py : For async functions, ensure proper async testing patterns are used with pytest for backend

Applied to files:

  • src/backend/tests/unit/helpers/test_flow_helpers.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/base/langflow/components/**/__init__.py : Update `__init__.py` with alphabetically sorted imports when adding new components

Applied to files:

  • src/lfx/src/lfx/components/flow_controls/run_flow.py
  • src/backend/base/langflow/helpers/flow.py
  • src/lfx/src/lfx/helpers/__init__.py
  • src/lfx/src/lfx/custom/custom_component/custom_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Test component build config updates by calling `to_frontend_node()` to get the node template, then calling `update_build_config()` to apply configuration changes

Applied to files:

  • src/lfx/src/lfx/components/flow_controls/run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/base/langflow/services/database/models/**/*.py : Database models should be organized by domain (api_key/, flow/, folder/, user/, etc.) under `src/backend/base/langflow/services/database/models/`

Applied to files:

  • src/backend/base/langflow/services/database/models/flow/model.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/base/langflow/api/**/*.py : Backend API endpoints should be organized by version (v1/, v2/) under `src/backend/base/langflow/api/` with specific modules for features (chat.py, flows.py, users.py, etc.)

Applied to files:

  • src/backend/base/langflow/helpers/flow.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : For component `run()` methods, use async/await pattern and return appropriate message types

Applied to files:

  • src/lfx/src/lfx/custom/custom_component/component.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/**/*.py : Use FastAPI async patterns with `await` for async operations in component execution methods

Applied to files:

  • src/lfx/src/lfx/custom/custom_component/component.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to src/backend/base/langflow/components/**/*.py : Add new components to the appropriate subdirectory under `src/backend/base/langflow/components/` (agents/, data/, embeddings/, input_output/, models/, processing/, prompts/, tools/, or vectorstores/)

Applied to files:

  • src/lfx/src/lfx/custom/custom_component/custom_component.py
📚 Learning: 2025-08-05T22:51:27.961Z
Learnt from: edwinjosechittilappilly
Repo: langflow-ai/langflow PR: 0
File: :0-0
Timestamp: 2025-08-05T22:51:27.961Z
Learning: The TestComposioComponentAuth test in src/backend/tests/unit/components/bundles/composio/test_base_composio.py demonstrates proper integration testing patterns for external API components, including real API calls with mocking for OAuth completion, comprehensive resource cleanup, and proper environment variable handling with pytest.skip() fallbacks.

Applied to files:

  • src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py
  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Inherit from the correct `ComponentTestBase` family class located in `src/backend/tests/base.py` based on API access needs: `ComponentTestBase` (no API), `ComponentTestBaseWithClient` (needs API), or `ComponentTestBaseWithoutClient` (pure logic). Provide three required fixtures: `component_class`, `default_kwargs`, and `file_names_mapping`

Applied to files:

  • src/backend/tests/unit/base/tools/test_run_flow.py
  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:47:28.965Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/testing.mdc:0-0
Timestamp: 2025-11-24T19:47:28.965Z
Learning: Applies to src/backend/tests/**/*.py : Use same filename as component with appropriate test prefix/suffix (e.g., `my_component.py` → `test_my_component.py`)

Applied to files:

  • src/backend/tests/unit/components/logic/test_run_flow_component.py
📚 Learning: 2025-11-24T19:46:09.074Z
Learnt from: CR
Repo: langflow-ai/langflow PR: 0
File: .cursor/rules/backend_development.mdc:0-0
Timestamp: 2025-11-24T19:46:09.074Z
Learning: Applies to tests/unit/components/**/*.py : Create unit tests in `src/backend/tests/unit/components/` mirroring the component directory structure, using `ComponentTestBaseWithClient` or `ComponentTestBaseWithoutClient` base classes

Applied to files:

  • src/backend/tests/unit/components/logic/test_run_flow_component.py
🧬 Code graph analysis (12)
src/backend/tests/unit/helpers/test_flow_helpers.py (3)
src/backend/base/langflow/helpers/flow.py (4)
  • get_flow_by_id_or_name (123-164)
  • list_flows (35-48)
  • list_flows_by_flow_folder (51-87)
  • list_flows_by_folder_id (90-120)
src/lfx/src/lfx/helpers/flow.py (4)
  • get_flow_by_id_or_name (172-202)
  • list_flows (66-85)
  • list_flows_by_flow_folder (88-131)
  • list_flows_by_folder_id (134-169)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
src/lfx/src/lfx/components/flow_controls/run_flow.py (2)
src/lfx/src/lfx/base/tools/run_flow.py (1)
  • RunFlowBaseComponent (29-728)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
src/backend/base/langflow/helpers/flow.py (3)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
src/backend/base/langflow/services/database/models/flow/model.py (2)
  • Flow (186-213)
  • to_data (198-208)
src/backend/tests/conftest.py (1)
  • flow (549-569)
src/lfx/tests/unit/helpers/test_flow_helpers.py (1)
src/backend/base/langflow/helpers/flow.py (8)
  • build_schema_from_inputs (364-381)
  • get_arg_names (384-397)
  • get_flow_by_id_or_name (123-164)
  • list_flows (35-48)
  • list_flows_by_flow_folder (51-87)
  • list_flows_by_folder_id (90-120)
  • load_flow (167-190)
  • run_flow (201-253)
src/lfx/src/lfx/custom/custom_component/component.py (2)
src/lfx/src/lfx/base/tools/run_flow.py (1)
  • update_outputs (432-463)
src/lfx/tests/unit/custom/custom_component/test_update_outputs.py (2)
  • update_outputs (95-111)
  • update_outputs (187-205)
src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts (2)
src/frontend/src/types/api/index.ts (1)
  • APIClassType (31-68)
src/frontend/src/controllers/API/helpers/constants.ts (1)
  • getURL (40-50)
src/lfx/src/lfx/helpers/__init__.py (1)
src/lfx/src/lfx/helpers/flow.py (5)
  • get_flow_by_id_or_name (172-202)
  • get_flow_inputs (20-29)
  • list_flows (66-85)
  • list_flows_by_flow_folder (88-131)
  • list_flows_by_folder_id (134-169)
src/lfx/src/lfx/custom/custom_component/custom_component.py (2)
src/backend/base/langflow/helpers/flow.py (4)
  • get_flow_by_id_or_name (123-164)
  • list_flows (35-48)
  • list_flows_by_flow_folder (51-87)
  • list_flows_by_folder_id (90-120)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
src/lfx/src/lfx/components/input_output/chat_output.py (1)
src/lfx/src/lfx/custom/custom_component/custom_component.py (1)
  • graph (191-192)
src/lfx/src/lfx/helpers/flow.py (2)
src/backend/base/langflow/helpers/flow.py (3)
  • list_flows_by_flow_folder (51-87)
  • list_flows_by_folder_id (90-120)
  • get_flow_by_id_or_name (123-164)
src/lfx/src/lfx/schema/data.py (1)
  • Data (26-288)
src/lfx/src/lfx/components/input_output/chat.py (2)
src/lfx/src/lfx/custom/custom_component/custom_component.py (1)
  • graph (191-192)
src/lfx/src/lfx/schema/message.py (2)
  • Message (34-299)
  • create (287-291)
src/backend/tests/unit/components/logic/test_run_flow_component.py (1)
src/lfx/src/lfx/components/flow_controls/run_flow.py (5)
  • get_selected_flow_meta (73-75)
  • load_graph_and_update_cfg (77-88)
  • should_update_stale_flow (90-96)
  • check_and_update_stale_flow (98-106)
  • update_build_config (24-71)
🪛 GitHub Actions: autofix.ci
src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx

[warning] 1-1: Unstaged changes detected after reset during autofix workflow. The file was modified and staged automatically.

src/frontend/src/components/core/dropdownComponent/index.tsx

[warning] 1-1: Unstaged changes detected after reset during autofix workflow. The file was modified and staged automatically.

src/frontend/src/types/components/index.ts

[warning] 1-1: Unstaged changes detected after reset during autofix workflow. The file was modified and staged automatically.

src/frontend/src/controllers/API/queries/nodes/use-post-template-value.ts

[warning] 1-1: Unstaged changes detected after reset during autofix workflow. The file was modified and staged automatically.

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (16)
  • GitHub Check: Lint Backend / Run Mypy (3.10)
  • GitHub Check: Lint Backend / Run Mypy (3.11)
  • GitHub Check: Lint Backend / Run Mypy (3.12)
  • GitHub Check: Run Frontend Tests / Determine Test Suites and Shard Distribution
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 5
  • GitHub Check: Run Backend Tests / Unit Tests - Python 3.10 - Group 1
  • 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 / LFX Tests - Python 3.10
  • GitHub Check: Run Frontend Unit Tests / Frontend Jest Unit Tests
  • GitHub Check: Run Backend Tests / Integration Tests - Python 3.10
  • GitHub Check: Test Starter Templates
  • GitHub Check: Optimize new Python code in this PR
  • GitHub Check: Update Component Index
  • GitHub Check: Update Starter Projects
🔇 Additional comments (62)
src/lfx/src/lfx/custom/custom_component/component.py (1)

580-583: LGTM! Clean async/sync compatibility pattern.

The conditional handling for both synchronous and asynchronous update_outputs implementations is well-implemented and follows the established pattern used elsewhere in this file (e.g., lines 1359-1362 for _get_tools). This provides excellent backward compatibility while supporting async operations.

src/lfx/src/lfx/components/input_output/chat.py (1)

92-101: LGTM! Correct session_id derivation and usage.

The implementation correctly derives the session_id with fallback to self.graph.session_id (line 92) and uses it consistently for both message creation (line 97) and the storage condition (line 101). This is the proper pattern.

Note: The session_id derivation logic is duplicated in chat_output.py (line 130) and could be extracted into a shared helper method on the base ChatComponent class, as suggested in the review of that file.

src/backend/base/langflow/services/database/models/flow/model.py (1)

198-208: LGTM!

The addition of folder_id to the to_data() serialization is consistent with the existing pattern and necessary for the new flow retrieval helpers that filter by folder.

src/lfx/src/lfx/inputs/input_mixin.py (1)

64-66: LGTM!

The override_skip field follows the existing pattern of boolean configuration options in the mixin. The integration with should_skip_field in param_handler.py correctly ensures fields with this flag are always processed.

src/lfx/src/lfx/graph/vertex/param_handler.py (1)

129-138: LGTM!

The override_skip guard is correctly placed as an early return before other skip conditions, ensuring fields with this flag are always processed regardless of other criteria.

src/backend/tests/unit/base/tools/test_run_flow.py (1)

24-687: Comprehensive test coverage.

The test suite thoroughly covers initialization, flow retrieval, caching, timestamp parsing, I/O handling, pre-run setup, and output resolution. Good use of mocking patterns and async test decorators.

src/lfx/src/lfx/helpers/flow.py (1)

172-202: Stub implementation is well-structured.

The get_flow_by_id_or_name stub correctly validates required parameters, logs a warning about the missing database backend, and returns None as expected. The docstring clearly explains this is a stub.

src/backend/base/langflow/helpers/flow.py (2)

70-84: Self-join query is well-constructed.

The aliased join pattern correctly finds flows in the same folder as the specified flow while excluding the source flow itself. The query filters properly by user ownership on both sides of the join.


30-33: SORT_DISPATCHER is a clean approach for dynamic ordering.

Mapping direction strings to SQLAlchemy ordering functions is a maintainable pattern that avoids repetitive conditional logic.

src/backend/tests/unit/components/logic/test_run_flow_component.py (3)

1-23: Test class organization follows project conventions.

The test file is well-organized with separate classes for initialization, helper methods, and build config testing. Metadata assertions in test_component_has_correct_metadata ensure component attributes remain stable.


504-555: Runtime integration test verifies critical flow execution path.

This test ensures the runtime correctly passes the cached updated_at timestamp to get_graph, which is essential for the cache freshness checking mechanism.


677-716: Good coverage of stale flow detection during refresh.

The test verifies that check_and_update_stale_flow is called when refreshing the flow list, ensuring stale flows are automatically updated.

src/lfx/src/lfx/helpers/__init__.py (1)

39-46: LGTM!

The new helper exports (get_flow_by_id_or_name, list_flows_by_flow_folder, list_flows_by_folder_id) are consistently added across all import branches (langflow, fallback, lfx) and properly exported in __all__. The alphabetical ordering is maintained as per the learnings.

Also applies to: 75-82, 111-118, 133-137

src/backend/tests/unit/helpers/test_flow_helpers.py (4)

1-12: LGTM!

Imports are well-organized and test file naming follows the test_*.py convention. The patch import from unittest.mock is correctly included for mocking database sessions.


15-48: LGTM!

The TestListFlows class correctly tests both the error case (missing user_id) and the database query path with proper async mocking of session_scope. The mock setup for the async context manager follows best practices.


50-114: LGTM!

Good test coverage for error cases and the basic query path. The test_list_flows_by_flow_folder_respects_order_params test validates that the function accepts order parameters without error; verifying actual ordering behavior would require more complex assertions on the SQL statement, which is acceptable to defer.


117-152: LGTM!

The TestListFlowsByFolderId class appropriately tests validation errors and the database query path, following the same consistent mocking pattern.

src/lfx/tests/unit/helpers/test_flow_helpers.py (7)

1-17: LGTM!

Imports are well-organized. The UUID import on line 2 is used on line 227 for the set_run_id assertion, so it's not unused.


20-42: LGTM!

Clear test that validates the filtering logic for input vertices.


45-63: LGTM!

Good validation of the schema building logic, including the field naming transformation from display names.


66-81: LGTM!

Clear test that validates the argument name extraction logic.


84-176: LGTM!

Comprehensive tests for the lfx stub implementations, correctly validating error handling and the expected empty/None return values.


179-189: LGTM!

Correctly validates that load_flow raises NotImplementedError in the lfx stub implementation.


192-283: LGTM!

Thorough test coverage for run_flow including error handling, graph property setting, input normalization (dict to list), and correct invocation of graph.arun. The tests properly validate the expected call arguments structure.

src/backend/tests/integration/base/tools/run_flow/test_run_flow_integration.py (6)

1-10: LGTM!

Imports are well-organized with proper separation between langflow and lfx dependencies. The integration test file follows the correct location pattern under src/backend/tests/integration/.


12-101: LGTM!

Excellent end-to-end integration test that validates the complete workflow including flow creation, update_build_config behavior, and proper exclusion of the current flow from options. Good use of try/finally for cleanup.


103-138: LGTM!

Good integration test for run_flow execution with real components, validating that graph properties are set correctly and the result structure is as expected.


141-226: LGTM!

Comprehensive integration test for tool generation from flows. Good validation of flow ownership and the ability to retrieve graphs and generate tools from real database flows.


229-284: LGTM!

Good test for output resolution with real flow structure. The use of SimpleNamespace to mock the _vertex attribute is a pragmatic approach for integration testing.


334-337: Verify assertion intent: == vs is.

The comment states "Expected same graph instance from cache" but the assertion uses == (equality) rather than is (identity). If the intent is to verify that caching returns the exact same object instance, use assert graph1 is graph2.

-            assert graph1 == graph2, "Expected same graph instance from cache"
+            assert graph1 is graph2, "Expected same graph instance from cache"
src/lfx/src/lfx/components/flow_controls/run_flow.py (5)

1-6: LGTM!

Imports are appropriate for the new functionality. datetime is needed for timestamp handling and Data for type annotations.


90-96: LGTM, though consider readability.

The logic using chained walrus operators is correct but dense. The current implementation works, but consider extracting the timestamp comparisons for clarity if maintenance becomes an issue.


98-106: LGTM!

The method correctly combines the stale check and update logic. The TODO comment on line 100 indicates awareness of potential future improvements.


108-110: LGTM!

Simple utility for ISO timestamp string conversion. The method name get_str_isots is a bit cryptic; get_iso_timestamp might be clearer, but this is a minor naming preference.


77-88: No issues found - review comment is incorrect.

The get_graph method signature shows that flow_name_selected and flow_id_selected are both optional parameters with default None. The method requires at least one of them (line 144-146 validates this), and the reviewed code provides flow_id_selected, satisfying the requirement. Passing only flow_id_selected and updated_at is valid and correct.

Likely an incorrect or invalid review comment.

src/lfx/src/lfx/custom/custom_component/custom_component.py (5)

15-22: LGTM - imports aligned with new flow helper utilities.

The imports properly bring in the new flow-discovery helpers that are used by the new methods in this file.


556-562: LGTM - consistent error handling pattern.

The refactored method properly delegates validation to the underlying list_flows helper and wraps exceptions consistently.


564-576: LGTM - handles missing flow_id gracefully.

Returning an empty list when flow_id is unavailable is appropriate for scenarios where the flow context isn't yet established (e.g., during component initialization).


578-590: LGTM - consistent implementation with sibling method.

The method follows the same pattern as alist_flows_by_flow_folder, ensuring API consistency.


637-655: LGTM - clean utility for attribute resolution.

The helper provides a clear fallback mechanism from runtime to frontend node attributes with good documentation.

src/lfx/src/lfx/base/tools/run_flow.py (19)

29-55: LGTM - well-structured initialization with cache dispatcher.

The dispatcher pattern cleanly organizes cache operations, and the instance variables for tracking run outputs and freshness are appropriately initialized.


56-96: LGTM - well-defined base inputs with appropriate configuration.

The inputs are properly configured with real_time_refresh for dynamic updates and override_skip=True to persist the flow ID to runtime.


101-119: LGTM - proper lifecycle management for dynamic output methods.

The method correctly clears old dynamic methods before registering new ones, preventing stale method references.


177-186: LGTM - correct field management logic.

The method properly preserves new fields and default keys while removing stale fields from the build config.


188-216: LGTM - good handling of display name collisions.

The use of Counter to detect duplicate vertex display names and the disambiguation logic with vertex ID suffixes is well implemented.


302-325: LGTM - efficient caching of run outputs.

The method correctly caches flow execution results to avoid redundant runs when resolving multiple outputs from the same flow execution.


327-361: LGTM - comprehensive output resolution with reasonable fallbacks.

The resolution logic correctly prioritizes exact matches in results and artifacts dictionaries before falling back to the complete output data.


383-402: LGTM - clean dynamic method registration pattern.

The use of MethodType to bind dynamic resolver functions is appropriate, and the sanitization of vertex/output names prevents invalid method names.


407-430: LGTM - proper preservation of tool output during sync.

The method correctly handles the tool output, ensuring it's preserved from the existing outputs map or found in the new outputs list.


432-463: LGTM - well-structured output update flow.

The method properly guards against invalid inputs and uses metadata for cache optimization when updating frontend node outputs.


468-507: LGTM - thorough output formatting with collision handling.

The display name logic correctly handles various scenarios: single output vertices, multiple outputs, and duplicate vertex display names.


509-526: LGTM - simple and well-validated utility.


531-556: LGTM - clean integration of cached graph with flow execution.

The method properly retrieves the cached graph, applies tweaks, and executes the flow.


561-587: LGTM - robust cache dispatcher with graceful error handling.

The method properly guards against disabled caching and missing services, with appropriate exception handling for non-critical cache operations.


618-629: LGTM - proper graph reconstruction from cache.

The method correctly handles missing data with appropriate fallbacks for description and updated_at fields.


631-646: LGTM - conservative cache freshness validation.

The timestamp comparison correctly requires both values to be present and uses a >= comparison, treating any cache with matching or newer timestamp as valid.


648-671: LGTM - thorough validation before cache deletion.

The method properly validates all required parameters including the edge case of whitespace-only flow IDs.


676-705: LGTM - clean data transformation for tweaks and inputs.

The methods correctly parse keyed field names into structured tweaks and build appropriate input payloads for flow execution.


720-728: LGTM - proper state reset for new flow execution.

The method correctly resets cached outputs and extracts fresh tweak data before each run.

src/frontend/src/components/core/parameterRenderComponent/components/dropdownComponent/index.tsx (1)

27-36: Selected metadata propagation looks correct

onChange now cleanly threads selectedMetadata through as selected_metadata only when provided, without altering existing value / load_from_db behavior. No issues from a type or flow perspective.

src/frontend/src/types/components/index.ts (1)

56-74: Dropdown onSelect API extension is backward‑compatible

Adding selectedMetadata?: any as a 4th argument aligns with the new dropdown usage and remains optional, so existing call sites stay valid.

src/frontend/src/CustomNodes/helpers/mutate-template.ts (1)

14-29: isRefresh flag is consistently threaded through the mutation path

The new isRefresh?: boolean parameter is correctly propagated into the debounced function and onto the mutation payload as is_refresh: isRefresh ?? false, so existing callers get false by default while refresh callers can opt into true. This keeps prior behavior intact and provides a clear switch for the backend.

Also applies to: 35-57, 90-101

@HzaRashid HzaRashid force-pushed the feat/runflow-improve branch from 2eabe13 to e6da1c2 Compare November 25, 2025 16:37
@HzaRashid HzaRashid changed the title Feat/runflow improve Feat: Runflow optimization and improved dropdown behavior Nov 25, 2025
@HzaRashid HzaRashid force-pushed the feat/runflow-improve branch 2 times, most recently from ff481bf to 41b4bd1 Compare November 25, 2025 17:06
misc: remove commented out code

feat: add refresh button and sort flows by updated_at date from most to least recent

ruff (flow.py imports)

improve fn contracts in runflow and improve flow id retrieval logic based on graph exec context

add dynamic outputs and optimize db lookups

add flow cache and db query for getting a single flow by id or name

cache run outputs and add refresh context to build config

misc

misc

use ids for flow retrieval

misc

fix missing flow_id bug

add unit and integration tests

add input field flag to persist hidden fields at runtime

move unit tests and change input and output display names

chore: update component index

fix: fix tool mode when flow has multiple inputs by dynamically creating resolvers

chore: update component index

ruff (run_flow and tests)

add resolvers to outputs map for non tool mode runtime

fix tests (current flow excluded in db fetch)

mypy (helpers/flow.py)

chore: update component index

remove unused code and clean up comments

fix: persist user messages in chat-based flows via session injection

chore: update component index

empty string fallback for sessionid in chat.py

chore: update component index

chore: update component index

cache invalidation with timestamps

misc

add cache invalidation

chore: update component index

chore: update comp idx

ruff (run_flow.py)

change session_id input type to MessageTextInput

chore: update component index

chore: update component index

chore: update component index

chore: update component index

sync starter projects with main

chore: update component index

chore: update component index

chore: update component index

remove dead code + impl coderabbit suggestions

chore: update component index

chore: update component index

clear options metadata before updating

chore: update component index

sync starter projects with main

sync starter projects with main

default param val (list flows)
Copy link
Member

@Cristhianzl Cristhianzl left a comment

Choose a reason for hiding this comment

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

lgtm

@HzaRashid HzaRashid force-pushed the feat/runflow-improve branch from e303c96 to 9631265 Compare November 25, 2025 18:30
@HzaRashid HzaRashid enabled auto-merge November 25, 2025 18:36
@HzaRashid HzaRashid added this pull request to the merge queue Nov 25, 2025
Merged via the queue into main with commit 1065e6e Nov 25, 2025
79 of 83 checks passed
@HzaRashid HzaRashid deleted the feat/runflow-improve branch November 25, 2025 19:01
Adam-Aghili pushed a commit that referenced this pull request Nov 25, 2025
* feat: optimize dropdown filtering and output resolution

misc: remove commented out code

feat: add refresh button and sort flows by updated_at date from most to least recent

ruff (flow.py imports)

improve fn contracts in runflow and improve flow id retrieval logic based on graph exec context

add dynamic outputs and optimize db lookups

add flow cache and db query for getting a single flow by id or name

cache run outputs and add refresh context to build config

misc

misc

use ids for flow retrieval

misc

fix missing flow_id bug

add unit and integration tests

add input field flag to persist hidden fields at runtime

move unit tests and change input and output display names

chore: update component index

fix: fix tool mode when flow has multiple inputs by dynamically creating resolvers

chore: update component index

ruff (run_flow and tests)

add resolvers to outputs map for non tool mode runtime

fix tests (current flow excluded in db fetch)

mypy (helpers/flow.py)

chore: update component index

remove unused code and clean up comments

fix: persist user messages in chat-based flows via session injection

chore: update component index

empty string fallback for sessionid in chat.py

chore: update component index

chore: update component index

cache invalidation with timestamps

misc

add cache invalidation

chore: update component index

chore: update comp idx

ruff (run_flow.py)

change session_id input type to MessageTextInput

chore: update component index

chore: update component index

chore: update component index

chore: update component index

sync starter projects with main

chore: update component index

chore: update component index

chore: update component index

remove dead code + impl coderabbit suggestions

chore: update component index

chore: update component index

clear options metadata before updating

chore: update component index

sync starter projects with main

sync starter projects with main

default param val (list flows)

* chore: update component index

* add integration tests

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes (attempt 2/3)

---------

Co-authored-by: Cristhian Zanforlin <[email protected]>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants