Skip to content

⚡️ Speed up function apply_tweaks by 12% in PR #11753 (fix-header-tweaks)#11754

Closed
codeflash-ai[bot] wants to merge 21 commits into
mainfrom
codeflash/optimize-pr11753-2026-02-12T14.11.41
Closed

⚡️ Speed up function apply_tweaks by 12% in PR #11753 (fix-header-tweaks)#11754
codeflash-ai[bot] wants to merge 21 commits into
mainfrom
codeflash/optimize-pr11753-2026-02-12T14.11.41

Conversation

@codeflash-ai
Copy link
Copy Markdown
Contributor

@codeflash-ai codeflash-ai Bot commented Feb 12, 2026

⚡️ This pull request contains optimizations for PR #11753

If you approve this dependent PR, these changes will be merged into the original PR branch fix-header-tweaks.

This PR will be automatically closed if the original PR is merged.


📄 12% (0.12x) speedup for apply_tweaks in src/backend/base/langflow/processing/process.py

⏱️ Runtime : 1.23 milliseconds 1.10 milliseconds (best of 118 runs)

📝 Explanation and details

The optimized code achieves an 11% speedup by reducing redundant dictionary lookups in the hot loop where tweaks are applied.

Key optimizations:

  1. Field caching via try/except: Instead of checking if tweak_name not in template_data followed by accessing template_data[tweak_name] multiple times (2-3 lookups per iteration), the code now does a single lookup with field = template_data[tweak_name] wrapped in try/except. This reduces dictionary hash lookups from ~3 per tweak to just 1.

  2. Reusing the field reference: Throughout the conditional branches, field["value"] and field[key] replace template_data[tweak_name]["value"] and template_data[tweak_name][key], eliminating repeated indexing into template_data.

  3. Flattened template_data extraction: The chain node.get("data", {}).get("node", {}).get("template") is broken into intermediate steps with type checking. While this adds lines, it's executed once per function call (outside the loop), so the cost is negligible.

Why this speeds up the code:

Python dictionaries require hashing keys and resolving collisions on each lookup. In the original code, for each tweak with valid tweak_name, the code performs:

  • 1 lookup to check tweak_name not in template_data (line profiler: 1.06ms, 7.6% of time)
  • 1 lookup to check tweak_name in template_data again (1.04ms, 7.4%)
  • 1-3 additional lookups when accessing template_data[tweak_name] to get field_type and set values

The optimized version uses try/except to merge the membership test with the first access, and then reuses the retrieved field object, cutting the number of dictionary operations roughly in half. Line profiler confirms this: the try/except block (929ns + 1.02ms) is faster than the original's two membership checks combined (1.06ms + 1.04ms = 2.1ms).

Impact based on test results:

  • The optimization shines when processing many tweaks (test test_large_scale_many_fields_and_tweaks with 1000 fields), where the reduction in dictionary operations compounds.
  • For workloads with high tweak counts per node or frequent apply_tweaks calls (e.g., test_sequential_apply_tweaks_calls), the cumulative savings become significant.
  • The speedup is consistent across different field types since the optimization applies to the common path before type-specific handling.

All security checks (code field protection), type-specific logic (NestedDict, mcp, dict, file), and error handling remain unchanged, ensuring correctness across all test cases.

Correctness verification report:

Test Status
⚙️ Existing Unit Tests 13 Passed
🌀 Generated Regression Tests 157 Passed
⏪ Replay Tests 🔘 None Found
🔎 Concolic Coverage Tests 🔘 None Found
📊 Tests Coverage 100.0%
⚙️ Click to see Existing Unit Tests
🌀 Click to see Generated Regression Tests
import copy  # used to deep-copy structures to assert changes vs original
from typing import Any, Dict

import pytest  # used for our unit tests
from langflow.processing.process import apply_tweaks
from lfx.processing.utils import validate_and_repair_json


def test_non_dict_template_logs_warning_and_ignores_tweaks(caplog):
    # Create a node whose template is not a dict (e.g., None)
    node: Dict[str, Any] = {"id": "node1", "data": {"node": {"template": None}}}
    node_tweaks = {"some_field": "value"}
    # Capture log output and call the function
    caplog.clear()
    apply_tweaks(node, node_tweaks)


def test_tweak_not_in_template_is_ignored():
    # Template contains only 'present_field'
    template = {"present_field": {"type": "text", "value": "original"}}
    node = {"id": "n2", "data": {"node": {"template": template}}}
    # Tweaks try to change a missing field 'absent_field' and should be ignored
    node_tweaks = {"absent_field": "new_value"}
    before = copy.deepcopy(node)
    apply_tweaks(node, node_tweaks)


def test_code_field_cannot_be_overridden_and_logs_security_warning(caplog):
    # Ensure attempts to override 'code' field do not change it and produce a security warning
    template = {"code": {"type": "text", "value": "safe_code"}}
    node = {"id": "n3", "data": {"node": {"template": template}}}
    node_tweaks = {"code": "malicious_code"}
    caplog.clear()
    apply_tweaks(node, node_tweaks)


def test_mcp_field_sets_value_directly():
    # MCP type should have its 'value' replaced directly with the tweak value (dict in this case)
    template = {"m": {"type": "mcp", "value": {"old": 1}}}
    node = {"id": "n4", "data": {"node": {"template": template}}}
    new_value = {"a": 1, "b": 2}
    apply_tweaks(node, {"m": new_value})


def test_dict_type_field_sets_value_when_tweak_is_dict():
    # For fields declared as type 'dict', a dict tweak should replace the 'value' key directly
    template = {"cfg": {"type": "dict", "value": {"x": 0}}}
    node = {"id": "n5", "data": {"node": {"template": template}}}
    new_cfg = {"x": 42, "y": "added"}
    apply_tweaks(node, {"cfg": new_cfg})


def test_nesteddict_uses_validate_and_repair_json():
    # For NestedDict, apply_tweaks uses validate_and_repair_json on the tweak value.
    # To compute the expected result, call the same utility directly.
    template = {"nested": {"type": "NestedDict", "value": {}}}
    node = {"id": "n6", "data": {"node": {"template": template}}}
    # Provide a tweak value that might need repair (use a simple JSON-like object)
    tweak_input = {"maybe": "ok"}
    # Compute expected result using the same utility used by apply_tweaks
    expected = validate_and_repair_json(tweak_input)
    apply_tweaks(node, {"nested": tweak_input})


def test_field_without_type_and_dict_tweak_adds_subkeys():
    # If a field has no explicit type and tweak is a dict, subkeys of the tweak should be added to the template entry
    template = {"free": {"value": "original"}}
    node = {"id": "n7", "data": {"node": {"template": template}}}
    tweak = {"alpha": 1, "beta": 2}
    apply_tweaks(node, {"free": tweak})
    # The template entry should now include the new keys set to their values
    for k, v in tweak.items():
        pass


def test_non_dict_tweak_sets_value_key_by_default():
    # For scalar tweaks (not dict), the 'value' key should be set (unless field type is 'file', which is tested separately)
    template = {"scalar": {"type": "", "value": "prev"}}
    node = {"id": "n8", "data": {"node": {"template": template}}}
    apply_tweaks(node, {"scalar": 123})


def test_file_field_with_non_dict_tweak_sets_file_path_key():
    # For file type fields, scalar tweaks should be assigned under 'file_path'
    template = {"f": {"type": "file"}}
    node = {"id": "n9", "data": {"node": {"template": template}}}
    apply_tweaks(node, {"f": "/tmp/myfile"})


def test_file_field_with_dict_tweak_sets_file_path_for_each_item():
    # When the tweak is a dict for a 'file' field, each tweak key will be assigned using 'file_path' as the key.
    # For deterministic behavior, use a one-key dict so we know exactly which value will end up in 'file_path'.
    template = {"filefield": {"type": "file", "value": {}}}
    node = {"id": "n10", "data": {"node": {"template": template}}}
    apply_tweaks(node, {"filefield": {"somekey": "/a/path"}})


def test_tweak_value_none_is_allowed_and_sets_value_key():
    # None is not a dict, so it should be set under the 'value' key for non-file types
    template = {"maybe_none": {"type": "text", "value": "was"}}
    node = {"id": "n11", "data": {"node": {"template": template}}}
    apply_tweaks(node, {"maybe_none": None})


def test_field_type_missing_defaults_to_value_key_for_scalars():
    # If the template entry has no 'type' key, fallback logic should still set 'value' on scalar tweaks
    template = {"no_type": {"value": 0}}
    node = {"id": "n12", "data": {"node": {"template": template}}}
    apply_tweaks(node, {"no_type": "updated"})


def test_large_scale_many_fields_and_tweaks():
    # Build a large template with 1000 fields to exercise loops and performance
    num = 1000
    template: Dict[str, Dict[str, Any]] = {}
    node_tweaks: Dict[str, Any] = {}
    # Populate template with a variety of types: 'mcp', 'dict', '', 'file' etc.
    for i in range(num):
        name = f"field_{i}"
        if i % 5 == 0:
            template[name] = {"type": "mcp", "value": {}}
            node_tweaks[name] = {"key": i}
        elif i % 5 == 1:
            template[name] = {"type": "dict", "value": {"old": i}}
            node_tweaks[name] = {"new": i}
        elif i % 5 == 2:
            template[name] = {"type": "file"}
            node_tweaks[name] = f"/tmp/path_{i}"
        elif i % 5 == 3:
            template[name] = {"type": "NestedDict", "value": {}}
            # use a structure that validate_and_repair_json can process
            node_tweaks[name] = {"maybe": i}
        else:
            # no explicit type; tweak provided as a dict to cause subkey assignment
            template[name] = {"value": None}
            node_tweaks[name] = {"sub": i}

    node = {"id": "big", "data": {"node": {"template": template}}}
    # Call the function once (should complete in reasonable time)
    apply_tweaks(node, node_tweaks)

    # Verify a sample of fields to assert correctness
    # Check several positions deterministically
    for i in (0, 1, 2, 3, 4, 250, 501, 999):
        fname = f"field_{i}"
        entry = node["data"]["node"]["template"][fname]
        if i % 5 == 0:
            pass
        elif i % 5 == 1:
            pass
        elif i % 5 == 2:
            pass
        elif i % 5 == 3:
            # NestedDict: value should be the validated/repaired version
            expected = validate_and_repair_json({"maybe": i})
        else:
            pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
#------------------------------------------------
from typing import Any
from unittest.mock import MagicMock, Mock, patch

# imports
import pytest
from langflow.processing.process import apply_tweaks


class TestApplyTweaksBasicFunctionality:
    """Basic tests for apply_tweaks function - verify fundamental functionality"""

    def test_empty_tweaks_does_nothing(self):
        """Test that applying empty tweaks dict doesn't modify node"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        original_value = node["data"]["node"]["template"]["field1"]["value"]
        apply_tweaks(node, {})

    def test_basic_string_field_tweak(self):
        """Test applying a basic string tweak to a simple field"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        tweaks = {"field1": "modified"}
        apply_tweaks(node, tweaks)

    def test_basic_integer_field_tweak(self):
        """Test applying an integer tweak to a field"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "int", "value": 10}
                    }
                }
            }
        }
        tweaks = {"field1": 42}
        apply_tweaks(node, tweaks)

    def test_basic_float_field_tweak(self):
        """Test applying a float tweak to a field"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "float", "value": 3.14}
                    }
                }
            }
        }
        tweaks = {"field1": 2.71}
        apply_tweaks(node, tweaks)

    def test_multiple_field_tweaks(self):
        """Test applying tweaks to multiple fields at once"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "str", "value": "a"},
                        "field2": {"type": "int", "value": 1},
                        "field3": {"type": "float", "value": 1.0}
                    }
                }
            }
        }
        tweaks = {"field1": "b", "field2": 2, "field3": 2.0}
        apply_tweaks(node, tweaks)

    def test_dict_field_type_with_dict_value(self):
        """Test that dict field type accepts dict values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "dict", "value": {}}
                    }
                }
            }
        }
        new_dict = {"key1": "val1", "key2": "val2"}
        tweaks = {"config": new_dict}
        apply_tweaks(node, tweaks)

    def test_mcp_field_type_with_dict_value(self):
        """Test that mcp field type accepts dict values directly"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "mcp_field": {"type": "mcp", "value": {}}
                    }
                }
            }
        }
        new_dict = {"server": "test_server"}
        tweaks = {"mcp_field": new_dict}
        apply_tweaks(node, tweaks)

    def test_nested_dict_field_type(self):
        """Test that NestedDict field type validates and repairs JSON"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "nested": {"type": "NestedDict", "value": {}}
                    }
                }
            }
        }
        tweaks = {"nested": {"nested_key": "nested_value"}}
        apply_tweaks(node, tweaks)


class TestApplyTweaksCodeFieldSecurity:
    """Tests for code field security restrictions"""

    def test_code_field_cannot_be_tweaked(self):
        """Test that 'code' field is protected from tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "code": {"type": "str", "value": "original_code"}
                    }
                }
            }
        }
        tweaks = {"code": "malicious_code"}
        apply_tweaks(node, tweaks)

    def test_code_field_with_other_tweaks(self):
        """Test that other fields are tweaked even when code field is present"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "code": {"type": "str", "value": "original_code"},
                        "other_field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        tweaks = {"code": "malicious_code", "other_field": "modified"}
        apply_tweaks(node, tweaks)


class TestApplyTweaksEdgeCases:
    """Edge case tests for apply_tweaks function"""

    def test_missing_data_key(self):
        """Test that function handles nodes with missing 'data' key gracefully"""
        node = {"id": "test_node"}
        tweaks = {"field1": "value"}
        # Should not raise an exception
        apply_tweaks(node, tweaks)

    def test_missing_node_key(self):
        """Test that function handles nodes with missing 'node' key gracefully"""
        node = {"id": "test_node", "data": {}}
        tweaks = {"field1": "value"}
        # Should not raise an exception
        apply_tweaks(node, tweaks)

    def test_missing_template_key(self):
        """Test that function handles nodes with missing 'template' key gracefully"""
        node = {"id": "test_node", "data": {"node": {}}}
        tweaks = {"field1": "value"}
        # Should not raise an exception
        apply_tweaks(node, tweaks)

    def test_template_is_none(self):
        """Test that function logs warning when template is None"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": None
                }
            }
        }
        tweaks = {"field1": "value"}
        apply_tweaks(node, tweaks)
        # Should return early without modifying anything

    def test_template_is_string_not_dict(self):
        """Test that function logs warning when template is not a dict"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": "not_a_dict"
                }
            }
        }
        tweaks = {"field1": "value"}
        apply_tweaks(node, tweaks)
        # Should return early without modifying anything

    def test_template_is_list_not_dict(self):
        """Test that function logs warning when template is a list"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": [1, 2, 3]
                }
            }
        }
        tweaks = {"field1": "value"}
        apply_tweaks(node, tweaks)
        # Should return early without modifying anything

    def test_tweak_field_not_in_template(self):
        """Test that tweaks for non-existent fields are skipped"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        tweaks = {"non_existent_field": "value"}
        apply_tweaks(node, tweaks)

    def test_file_field_type_with_scalar_value(self):
        """Test that file field type with scalar value uses file_path key"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "file_field": {"type": "file"}
                    }
                }
            }
        }
        tweaks = {"file_field": "/path/to/file.txt"}
        apply_tweaks(node, tweaks)

    def test_file_field_type_with_dict_value(self):
        """Test that file field type with dict value uses file_path for keys"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "file_field": {"type": "file"}
                    }
                }
            }
        }
        tweaks = {"file_field": {"path": "/path/to/file.txt"}}
        apply_tweaks(node, tweaks)

    def test_non_file_field_type_with_dict_value(self):
        """Test that non-file field types with dict values keep original keys"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "custom_field": {"type": "custom"}
                    }
                }
            }
        }
        tweaks = {"custom_field": {"key1": "val1", "key2": "val2"}}
        apply_tweaks(node, tweaks)

    def test_field_with_missing_type(self):
        """Test that fields without 'type' key are handled correctly"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"value": "original"}
                    }
                }
            }
        }
        tweaks = {"field1": "modified"}
        apply_tweaks(node, tweaks)

    def test_empty_template_dict(self):
        """Test that empty template dict is handled correctly"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {}
                }
            }
        }
        tweaks = {"field1": "value"}
        apply_tweaks(node, tweaks)
        # Should not raise an exception

    def test_boolean_value_tweak(self):
        """Test applying boolean value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "flag": {"type": "bool", "value": False}
                    }
                }
            }
        }
        tweaks = {"flag": True}
        apply_tweaks(node, tweaks)

    def test_none_value_tweak(self):
        """Test applying None value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        tweaks = {"field": None}
        apply_tweaks(node, tweaks)

    def test_empty_string_value_tweak(self):
        """Test applying empty string value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        tweaks = {"field": ""}
        apply_tweaks(node, tweaks)

    def test_zero_value_tweak(self):
        """Test applying zero value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "int", "value": 100}
                    }
                }
            }
        }
        tweaks = {"field": 0}
        apply_tweaks(node, tweaks)

    def test_empty_dict_value_tweak(self):
        """Test applying empty dict value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "dict", "value": {"key": "val"}}
                    }
                }
            }
        }
        tweaks = {"config": {}}
        apply_tweaks(node, tweaks)

    def test_nested_dict_tweak(self):
        """Test applying nested dict value tweaks"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "dict", "value": {}}
                    }
                }
            }
        }
        nested = {"outer": {"inner": "value"}}
        tweaks = {"config": nested}
        apply_tweaks(node, tweaks)

    def test_special_characters_in_string_value(self):
        """Test tweaking with special characters in string value"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        special_value = "!@#$%^&*()_+-=[]{}|;':\",./<>?"
        tweaks = {"field": special_value}
        apply_tweaks(node, tweaks)

    def test_unicode_string_value(self):
        """Test tweaking with unicode string values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        unicode_value = "Hello 世界 🌍 Привет"
        tweaks = {"field": unicode_value}
        apply_tweaks(node, tweaks)

    def test_very_large_string_value(self):
        """Test tweaking with very large string values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        large_value = "x" * 10000
        tweaks = {"field": large_value}
        apply_tweaks(node, tweaks)

    def test_very_large_negative_number(self):
        """Test tweaking with very large negative numbers"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "int", "value": 0}
                    }
                }
            }
        }
        tweaks = {"field": -999999999999}
        apply_tweaks(node, tweaks)

    def test_scientific_notation_number(self):
        """Test tweaking with scientific notation numbers"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "float", "value": 0.0}
                    }
                }
            }
        }
        tweaks = {"field": 1.23e-10}
        apply_tweaks(node, tweaks)

    def test_list_value_as_dict_values(self):
        """Test tweaking with dict containing list values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "custom"}
                    }
                }
            }
        }
        tweaks = {"config": {"items": [1, 2, 3]}}
        apply_tweaks(node, tweaks)

    def test_multiple_dict_keys_with_file_type(self):
        """Test file type with multiple dict keys converts all to file_path"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "file_field": {"type": "file"}
                    }
                }
            }
        }
        tweaks = {"file_field": {"key1": "val1", "key2": "val2"}}
        apply_tweaks(node, tweaks)

    def test_node_with_multiple_fields_selective_tweak(self):
        """Test that only specified fields are tweaked when multiple exist"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field1": {"type": "str", "value": "a"},
                        "field2": {"type": "str", "value": "b"},
                        "field3": {"type": "str", "value": "c"}
                    }
                }
            }
        }
        tweaks = {"field1": "x", "field3": "z"}
        apply_tweaks(node, tweaks)


class TestApplyTweaksLargeScale:
    """Large-scale tests for apply_tweaks function"""

    def test_many_tweaks_on_single_node(self):
        """Test applying many tweaks to a single node"""
        template = {}
        for i in range(500):
            template[f"field_{i}"] = {"type": "str", "value": f"original_{i}"}
        
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": template
                }
            }
        }
        
        tweaks = {}
        for i in range(500):
            tweaks[f"field_{i}"] = f"modified_{i}"
        
        apply_tweaks(node, tweaks)
        
        # Verify all tweaks were applied
        for i in range(500):
            pass

    def test_large_dict_field_value(self):
        """Test tweaking with very large dict values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "dict", "value": {}}
                    }
                }
            }
        }
        
        large_dict = {f"key_{i}": f"value_{i}" for i in range(1000)}
        tweaks = {"config": large_dict}
        apply_tweaks(node, tweaks)
        for i in range(1000):
            pass

    def test_deeply_nested_dict_value(self):
        """Test tweaking with deeply nested dict values"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "dict", "value": {}}
                    }
                }
            }
        }
        
        # Create a deeply nested dict
        nested = current = {}
        for i in range(100):
            current[f"level_{i}"] = {}
            current = current[f"level_{i}"]
        current["final"] = "value"
        
        tweaks = {"config": nested}
        apply_tweaks(node, tweaks)

    def test_many_fields_partial_tweaks(self):
        """Test applying tweaks to subset of many fields"""
        template = {}
        for i in range(1000):
            template[f"field_{i}"] = {"type": "str", "value": f"original_{i}"}
        
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": template
                }
            }
        }
        
        # Only tweak every 10th field
        tweaks = {}
        for i in range(0, 1000, 10):
            tweaks[f"field_{i}"] = f"modified_{i}"
        
        apply_tweaks(node, tweaks)
        
        # Verify tweaked fields
        for i in range(0, 1000, 10):
            pass
        
        # Verify untweaked fields remain original
        for i in range(1, 1000, 10):
            pass

    def test_tweak_with_many_dict_entries(self):
        """Test applying dict tweaks with many entries"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "config": {"type": "custom"}
                    }
                }
            }
        }
        
        large_dict = {f"entry_{i}": f"data_{i}" for i in range(500)}
        tweaks = {"config": large_dict}
        apply_tweaks(node, tweaks)
        
        for i in range(500):
            pass

    def test_sequential_apply_tweaks_calls(self):
        """Test applying tweaks sequentially multiple times"""
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": {
                        "field": {"type": "str", "value": "original"}
                    }
                }
            }
        }
        
        # Apply tweaks 100 times in sequence
        for i in range(100):
            tweaks = {"field": f"value_{i}"}
            apply_tweaks(node, tweaks)

    def test_different_field_types_at_scale(self):
        """Test tweaking many different field types"""
        template = {}
        types = ["str", "int", "float", "bool", "file", "dict", "mcp", "NestedDict", "custom"]
        
        for i in range(500):
            field_type = types[i % len(types)]
            template[f"field_{i}"] = {"type": field_type, "value": None}
        
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": template
                }
            }
        }
        
        tweaks = {}
        for i in range(500):
            field_type = types[i % len(types)]
            if field_type in ["dict", "mcp", "NestedDict", "custom"]:
                tweaks[f"field_{i}"] = {"key": f"value_{i}"}
            elif field_type == "bool":
                tweaks[f"field_{i}"] = i % 2 == 0
            elif field_type == "float":
                tweaks[f"field_{i}"] = float(i)
            elif field_type == "int":
                tweaks[f"field_{i}"] = i
            else:
                tweaks[f"field_{i}"] = f"value_{i}"
        
        apply_tweaks(node, tweaks)

    def test_many_tweaks_with_code_field_protection(self):
        """Test that code field is skipped even with many tweaks"""
        template = {"code": {"type": "str", "value": "original_code"}}
        for i in range(100):
            template[f"field_{i}"] = {"type": "str", "value": f"original_{i}"}
        
        node = {
            "id": "test_node",
            "data": {
                "node": {
                    "template": template
                }
            }
        }
        
        tweaks = {"code": "modified_code"}
        for i in range(100):
            tweaks[f"field_{i}"] = f"modified_{i}"
        
        apply_tweaks(node, tweaks)
        # Other fields should be modified
        for i in range(100):
            pass

    def test_stress_test_mixed_operations(self):
        """Stress test with mixed operations and field types"""
        # Create a template with various types and structures
        template = {}
        for i in range(200):
            if i % 5 == 0:
                template[f"field_{i}"] = {"type": "NestedDict", "value": {}}
            elif i % 5 == 1:
                template[f"field_{i}"] = {"type": "mcp", "value": {}}
            elif i % 5 == 2:
                template[f"field_{i}"] = {"type": "dict", "value": {}}
            elif i % 5 == 3:
                template[f"field_{i}"] = {"type": "file", "value": ""}
            else:
                template[f"field_{i}"] = {"type": "str", "value": ""}
        
        node = {
            "id": "stress_test",
            "data": {
                "node": {
                    "template": template
                }
            }
        }
        
        # Apply many tweaks
        tweaks = {}
        for i in range(200):
            if i % 5 == 0:
                tweaks[f"field_{i}"] = {"data": f"nested_{i}"}
            elif i % 5 == 1:
                tweaks[f"field_{i}"] = {"mcp_config": f"config_{i}"}
            elif i % 5 == 2:
                tweaks[f"field_{i}"] = {f"key_{i}": f"value_{i}"}
            elif i % 5 == 3:
                tweaks[f"field_{i}"] = f"/path/to/file_{i}.txt"
            else:
                tweaks[f"field_{i}"] = f"string_{i}"
        
        apply_tweaks(node, tweaks)
        
        # Verify results
        for i in range(200):
            if i % 5 == 3:
                pass
            else:
                pass
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.

To edit these changes git checkout codeflash/optimize-pr11753-2026-02-12T14.11.41 and push.

Codeflash

HimavarshaVS and others added 21 commits February 9, 2026 12:02
feat(auth): Pluggable AuthService with abstract base class (#10702)

* feat: Introduce service registration decorator and enhance ServiceManager for pluggable service discovery

- Added `register_service` decorator to allow services to self-register with the ServiceManager.
- Enhanced `ServiceManager` to support multiple service discovery mechanisms, including decorator-based registration, config files, and entry points.
- Implemented methods for direct service class registration and plugin discovery from various sources, improving flexibility and extensibility of service management.

* feat: Implement VariableService for managing environment variables

- Introduced VariableService class to handle environment variables with in-memory caching.
- Added methods for getting, setting, deleting, and listing variables.
- Included logging for service initialization and variable operations.
- Created an __init__.py file to expose VariableService in the package namespace.

* feat: Enhance LocalStorageService with Service integration and async teardown

- Updated LocalStorageService to inherit from both StorageService and Service for improved functionality.
- Added a name attribute for service identification.
- Implemented an async teardown method for future extensibility, even though no cleanup is currently needed.
- Refactored the constructor to ensure proper initialization of both parent classes.

* feat: Implement telemetry service with abstract base class and minimal logging functionality

- Added `BaseTelemetryService` as an abstract base class defining the interface for telemetry services.
- Introduced `TelemetryService`, a lightweight implementation that logs telemetry events without sending data.
- Created `__init__.py` to expose the telemetry service in the package namespace.
- Ensured robust async methods for logging various telemetry events and handling exceptions.

* feat: Introduce BaseTracingService and implement minimal TracingService

- Added `BaseTracingService` as an abstract base class defining the interface for tracing services.
- Implemented `TracingService`, a lightweight version that logs trace events without external integrations.
- Included async methods for starting and ending traces, tracing components, and managing logs and outputs.
- Enhanced documentation for clarity on method usage and parameters.

* feat: Add unit tests for service registration decorators

- Introduced a new test suite for validating the functionality of the @register_service decorator.
- Implemented tests for various service types including LocalStorageService, TelemetryService, and TracingService.
- Verified behavior for service registration with and without overrides, ensuring correct service management.
- Included tests for custom service implementations and preservation of class functionality.
- Enhanced overall test coverage for the service registration mechanism.

* feat: Add comprehensive unit and integration tests for ServiceManager

- Introduced a suite of unit tests covering edge cases for service registration, lifecycle management, and dependency resolution.
- Implemented integration tests to validate service loading from configuration files and environment variables.
- Enhanced test coverage for various service types including LocalStorageService, TelemetryService, and VariableService.
- Verified behavior for service registration with and without overrides, ensuring correct service management.
- Ensured robust handling of error conditions and edge cases in service creation and configuration parsing.

* feat: Add unit and integration tests for minimal service implementations

- Introduced comprehensive unit tests for LocalStorageService, TelemetryService, TracingService, and VariableService.
- Implemented integration tests to validate the interaction between minimal services.
- Ensured robust coverage for file operations, service readiness, and exception handling.
- Enhanced documentation within tests for clarity on functionality and expected behavior.

* docs: Add detailed documentation for pluggable services architecture and usage

* feat: Add example configuration file for Langflow services

* docs: Update PLUGGABLE_SERVICES.md to enhance architecture benefits section

- Revised the documentation to highlight the advantages of the pluggable service system.
- Replaced the migration guide with a detailed overview of features such as automatic discovery, lazy instantiation, dependency injection, and lifecycle management.
- Clarified examples of service registration and improved overall documentation for better understanding.

* [autofix.ci] apply automated fixes

* test(services): improve variable service teardown test with public API assertions

* docs(pluggable-service-layer): add docstrings for service manager and implementations

* fix: remove duplicate teardown method from LocalStorageService

During rebase, the teardown method was added in two locations (lines 57 and 220).
Removed the duplicate at line 57, keeping the one at the end of the class (line 220)
which is the more appropriate location for cleanup methods.

* fix(tests): update service tests for LocalStorageService constructor changes

- Add MockSessionService fixtures to test files that use ServiceManager
- Update LocalStorageService test instantiation to use mock session and settings services
- Fix service count assertions to account for MockSessionService in fixtures
- Remove duplicate class-level clean_manager fixtures in test_edge_cases.py

These changes fix test failures caused by LocalStorageService requiring
session_service and settings_service parameters instead of just data_dir.

* fix(services): Harden service lifecycle methods

- Fixed Diamond Inheritance in LocalStorageService
- Added Circular Dependency Detection in _create_service_from_class
- Fixed StorageService.teardown to Have Default Implementation

* docs: Update discovery order for pluggable services

* fix(lfx): replace aiofile with aiofiles for CI compatibility

- The aiofile library uses native async I/O (libaio) which fails with
  EAGAIN (SystemError: 11, 'Resource temporarily unavailable') in
  containerized environments like GitHub Actions runners.
- Switch to aiofiles which uses thread pool executors, providing reliable
  async file I/O across all environments including containers.

* [autofix.ci] apply automated fixes

* fix(lfx): prevent race condition in plugin discovery

  The discover_plugins() method had a TOCTOU (time-of-check to time-of-use)
  race condition. Since get() uses a keyed lock (per service name), multiple
  threads requesting different services could concurrently see
  _plugins_discovered=False and trigger duplicate plugin discovery.

  Wrap discover_plugins() with self._lock to ensure thread-safe access to
  the _plugins_discovered flag and prevent concurrent discovery execution.

* [autofix.ci] apply automated fixes

* feat: Introduce service registration decorator and enhance ServiceManager for pluggable service discovery

- Added `register_service` decorator to allow services to self-register with the ServiceManager.
- Enhanced `ServiceManager` to support multiple service discovery mechanisms, including decorator-based registration, config files, and entry points.
- Implemented methods for direct service class registration and plugin discovery from various sources, improving flexibility and extensibility of service management.

* feat: Enhance LocalStorageService with Service integration and async teardown

- Updated LocalStorageService to inherit from both StorageService and Service for improved functionality.
- Added a name attribute for service identification.
- Implemented an async teardown method for future extensibility, even though no cleanup is currently needed.
- Refactored the constructor to ensure proper initialization of both parent classes.

* docs(pluggable-service-layer): add docstrings for service manager and implementations

* feat(auth): implement abstract base class for authentication services and add auth service retrieval function

* refactor(auth): move authentication logic from utils to AuthService

  Consolidate all authentication methods into the AuthService class to
  enable pluggable authentication implementations. The utils module now
  contains thin wrappers that delegate to the registered auth service.

  This allows alternative auth implementations (e.g., OIDC) to be
  registered via the pluggable services system while maintaining
  backward compatibility with existing code that imports from utils.

  Changes:
  - Move all auth logic (token creation, user validation, API key
    security, password hashing, encryption) to AuthService
  - Refactor utils.py to delegate to get_auth_service()
  - Update function signatures to remove settings_service parameter
    (now obtained from the service internally)

* refactor(auth): update authentication methods and remove settings_service parameter

  - Changed function to retrieve current user from access token instead of JWT.
  - Updated AuthServiceFactory to specify SettingsService type in create method.
  - Removed settings_service dependency from encryption and decryption functions, simplifying the code.

This refactor enhances the clarity and maintainability of the authentication logic.

* test(auth): add unit tests for AuthService and pluggable authentication

- Introduced comprehensive unit tests for AuthService, covering token creation, user validation, and authentication methods.
- Added tests for pluggable authentication, ensuring correct delegation to registered services.
- Enhanced test coverage for user authentication scenarios, including active/inactive user checks and token validation.

These additions improve the reliability and maintainability of the authentication system.

* fix(tests): update test cases to use AuthService and correct user retrieval method

- Replaced the mock for retrieving the current user from JWT to access token in the TestSuperuserCommand.
- Refactored unit tests for MCP encryption to utilize AuthService instead of a mock settings service, enhancing test reliability.
- Updated patch decorators in tests to reflect the new method of obtaining the AuthService, ensuring consistency across test cases.

These changes improve the accuracy and maintainability of the authentication tests.

* docs(pluggable-services): add auth_service to ServiceType enum documentation

* fix(auth): Add missing type hints and abstract methods to AuthServiceBase (#10710)




* [autofix.ci] apply automated fixes

* fix(auth): refactor api_key_security method to accept optional database session and improve error handling

* feat(auth): enhance AuthServiceBase with detailed design principles and JIT provisioning methods

* fix(auth): remove settings_service from encrypt/decrypt_api_key calls

After the pluggable auth refactor, encrypt_api_key and decrypt_api_key
no longer take a settings_service argument - they get it internally.

- Update check_key import path in __main__.py (moved to crud module)
- Remove settings_service argument from calls in:
  - api/v1/api_key.py
  - api/v1/store.py
  - services/variable/service.py
  - services/variable/kubernetes.py
- Fix auth service to use session_scope() instead of non-existent
  get_db_service().with_session()

* fix(auth): resolve type errors and duplicate definitions in pluggable auth branch

  - Add missing imports in auth/utils.py (Final, HTTPException, status,
    logger, SettingsService) that prevented application startup
  - Remove duplicate NoServiceRegisteredError class in lfx/services/manager.py
  - Remove duplicate teardown method in lfx/services/storage/local.py
  - Fix invalid settings_service parameter in encrypt_api_key calls
    in variable/service.py and variable/kubernetes.py
  - Add proper type guards for check_key calls to satisfy mypy
  - Add null checks for password fields in users.py endpoints

* [autofix.ci] apply automated fixes

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

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

* [autofix.ci] apply automated fixes

* replace jose with pyjwt

* [autofix.ci] apply automated fixes

* starter projects

* fix BE mcp tests

* [autofix.ci] apply automated fixes

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

* remive legacy usage of session

* fix user tests

* [autofix.ci] apply automated fixes

* fix lfx tests

* starter project update

* [autofix.ci] apply automated fixes

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

* fix mypy errors

* fix mypy errors on tests

* fix tests for decrypt_api_key

* resolve conflicts in auth utils

* [autofix.ci] apply automated fixes

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

* Add pluggable authentication factory with provider enum

* Add SSO feature flags to AuthSettings

* Add SSO fields to User model

* Add SSO configuration loader with YAML support

* Add unit tests for SSO configuration loader

* Add SSO configuration database model and CRUD operations

* Add CRUD operations for SSO configuration management

* Add SSO configuration service supporting both file and database configs

* Add example SSO configuration file with W3ID and other providers

* Implement OIDC authentication service with discovery and JIT provisioning

* Update AuthServiceFactory to instantiate OIDC service when SSO enabled

* Improve JWT token validation and API key decryption error handling

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* fix: resolve ruff linting errors in auth services and add sso-config.yaml to gitignore

* [autofix.ci] apply automated fixes

* fix: use correct function name get_current_user_from_access_token in login endpoint

* fix: remove incorrect settings_service parameter from decrypt_api_key call

* fix: correct encryption logic to properly detect plaintext vs encrypted values

* [autofix.ci] apply automated fixes

* fix tests

* [autofix.ci] apply automated fixes

* fix mypy errors

* fix tests

* [autofix.ci] apply automated fixes

* fix ruff errors

* fix tests in service

* [autofix.ci] apply automated fixes

* fix test security cors

* [autofix.ci] apply automated fixes

* fix webhook issues

* modify component index

* [autofix.ci] apply automated fixes

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

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

* fix webhook tests

* [autofix.ci] apply automated fixes

* build component index

* remove SSO functionality

* [autofix.ci] apply automated fixes

* fix variable creation

* [autofix.ci] apply automated fixes

* refactor: move MCPServerConfig schema to a separate file and update model_dump usage

* refactor: streamline AuthServiceFactory to use service_class for instance creation

* handle access token type

* [autofix.ci] apply automated fixes

* remove SSO fields from user model

* [autofix.ci] apply automated fixes

* replace is_encrypted back

* fix mypy errors

* remove sso config example

* feat: Refactor framework agnostic auth service (#11565)

* modify auth service layer

* [autofix.ci] apply automated fixes

* fix ruff errorrs

* [autofix.ci] apply automated fixes

* Update src/backend/base/langflow/services/deps.py



* address review comments

* [autofix.ci] apply automated fixes

* fix ruff errors

* remove cache

---------




* move base to lfx

* [autofix.ci] apply automated fixes

* resolve review comments

* [autofix.ci] apply automated fixes

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

* add auth protocol

* [autofix.ci] apply automated fixes

* revert models.py execption handling

* revert wrappers to ensure backwards compatibility

* fix http error code

* fix FE tests

* fix test_variables.py

* [autofix.ci] apply automated fixes

* fix ruff errors

* fix tests

* add wrappers for create token methods

* fix ruff errors

* [autofix.ci] apply automated fixes

* update error message

* modify status code for inactive user

* fix ruff errors

* fix patch for webhook tests

* fix error message when getting active users

---------

Co-authored-by: Gabriel Luiz Freitas Almeida <gabriel@logspace.ai>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Mike Pawlowski <mike.pawlowski@datastax.com>
Co-authored-by: Mike Pawlowski <mpawlow@ca.ibm.com>
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: ogabrielluiz <24829397+ogabrielluiz@users.noreply.github.com>
Co-authored-by: Deon Sanchez <69873175+deon-sanchez@users.noreply.github.com>
Co-authored-by: codeflash-ai[bot] <148906541+codeflash-ai[bot]@users.noreply.github.com>
* revert textarea to old classes

* fixed text-area-wrapper to handle initial height when value is calculated

* fixed playground padding

* fixed no input text size

* [autofix.ci] apply automated fixes

* fixed flaky test

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Create guardrails.py

* [autofix.ci] apply automated fixes

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

* Update guardrails.py

* [autofix.ci] apply automated fixes

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

* tests: add unit tests for GuardrailsComponent functionality

* [autofix.ci] apply automated fixes

* fix: resolve linting errors in GuardrailsComponent and tests

- Fix line length issues (E501) by breaking long strings
- Fix docstring formatting (D205, D415) in _check_guardrail
- Use ternary operator for response content extraction (SIM108)
- Replace magic value with named constant (PLR2004)
- Move return to else block per try/except best practices (TRY300)
- Catch specific exceptions instead of blind Exception (BLE001)
- Use list comprehension for checks_to_run (PERF401)
- Mark unused variables with underscore prefix (RUF059, F841)
- Add noqa comment for intentionally unused mock argument (ARG002)

* [autofix.ci] apply automated fixes

* refactor: address pr comments

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

* [autofix.ci] apply automated fixes

* feat: enhance heuristic detection with configurable threshold and scoring system

* refactor: simplify heuristic test assertions by removing unused variable

* [autofix.ci] apply automated fixes

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

* feat: enhance guardrail validation logic and input handling

* refactor: streamline import statements and clean up whitespace in guardrails component

* [autofix.ci] apply automated fixes

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

* Fix: update empty input handling tests to raise ValueError and refactor related assertions

* [autofix.ci] apply automated fixes

* [autofix.ci] apply automated fixes

* feat: add Guardrails component with unit tests

Add LLM-based guardrails component for detecting PII, tokens/passwords,
jailbreak attempts, and custom guardrail rules, along with comprehensive
unit tests.

* [autofix.ci] apply automated fixes

* fix: try removing logs

* [autofix.ci] apply automated fixes

---------

Co-authored-by: Lucas Democh <ldgoularte@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* Implemented dismiss file functionality on input file component

* fixed hover behavior

* added test for removing file from input

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fixed react flow utils to clean advanced edges

* Make connected handles not be able to be hidden

* Added test for hiding connected handles

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
fix tooltip showing up when closing select
* fix(frontend): prevent crash when renaming empty sessions

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…#11722)

The regex in langflow_pre_release_tag.py expected a dot before `rc`
(e.g. `1.8.0.rc0`), but PyPI returns PEP 440-normalized versions
without the dot (e.g. `1.8.0rc0`). This caused the script to recompute
the same version instead of incrementing, and `uv publish` silently
skipped the duplicate upload.

Update the regex to accept both formats with `\.?rc`.
…11725)

* fix: align chat history with input field in fullscreen playground

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
* fix singleton webhook on flow

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
…Variable button (#11723)

* fix: generate unique variable names in Prompt Template Add Variable button

Previously, clicking the Add Variable button always inserted {variable_name},
causing duplicate text without creating new input fields. Now the button
generates incremental names (variable_name, variable_name_1, variable_name_2)
by checking existing variables in the template.

* refactor: extract generateUniqueVariableName and import in tests

Extract the variable name generation logic into an exported function
so tests can import and validate the actual production code instead
of testing a duplicated copy of the logic.
…11709)

add edge between components

Co-authored-by: Olayinka Adelakun <olayinkaadelakun@Olayinkas-MacBook-Pro.local>
)

* Update state when exiting modal on accordion prompt component

* Added isDoubleBrackets and show correct modal and use correct brackets when mustache is enabled

* [autofix.ci] apply automated fixes

* added test to see if state is synchronized and mustache is enabled

* [autofix.ci] apply automated fixes

* updated mustache id and removed extra prompt call

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Carlos Coelho <80289056+carlosrcoelho@users.noreply.github.com>
…es (#11720)

* fix(frontend): add Safari-specific padding for playground chat messages

* [autofix.ci] apply automated fixes

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
The optimized code achieves an **11% speedup** by reducing redundant dictionary lookups in the hot loop where tweaks are applied.

**Key optimizations:**

1. **Field caching via try/except**: Instead of checking `if tweak_name not in template_data` followed by accessing `template_data[tweak_name]` multiple times (2-3 lookups per iteration), the code now does a single lookup with `field = template_data[tweak_name]` wrapped in try/except. This reduces dictionary hash lookups from ~3 per tweak to just 1.

2. **Reusing the field reference**: Throughout the conditional branches, `field["value"]` and `field[key]` replace `template_data[tweak_name]["value"]` and `template_data[tweak_name][key]`, eliminating repeated indexing into `template_data`.

3. **Flattened template_data extraction**: The chain `node.get("data", {}).get("node", {}).get("template")` is broken into intermediate steps with type checking. While this adds lines, it's executed once per function call (outside the loop), so the cost is negligible.

**Why this speeds up the code:**

Python dictionaries require hashing keys and resolving collisions on each lookup. In the original code, for each tweak with valid `tweak_name`, the code performs:
- 1 lookup to check `tweak_name not in template_data` (line profiler: 1.06ms, 7.6% of time)
- 1 lookup to check `tweak_name in template_data` again (1.04ms, 7.4%)  
- 1-3 additional lookups when accessing `template_data[tweak_name]` to get field_type and set values

The optimized version uses try/except to merge the membership test with the first access, and then reuses the retrieved `field` object, cutting the number of dictionary operations roughly in half. Line profiler confirms this: the try/except block (929ns + 1.02ms) is faster than the original's two membership checks combined (1.06ms + 1.04ms = 2.1ms).

**Impact based on test results:**

- The optimization shines when processing many tweaks (test `test_large_scale_many_fields_and_tweaks` with 1000 fields), where the reduction in dictionary operations compounds.
- For workloads with high tweak counts per node or frequent `apply_tweaks` calls (e.g., `test_sequential_apply_tweaks_calls`), the cumulative savings become significant.
- The speedup is consistent across different field types since the optimization applies to the common path before type-specific handling.

All security checks (code field protection), type-specific logic (NestedDict, mcp, dict, file), and error handling remain unchanged, ensuring correctness across all test cases.
@codeflash-ai codeflash-ai Bot added the ⚡️ codeflash Optimization PR opened by Codeflash AI label Feb 12, 2026
@github-actions github-actions Bot added the community Pull Request from an external contributor label Feb 12, 2026
@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 12, 2026

Codecov Report

❌ Patch coverage is 66.03352% with 304 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.06%. Comparing base (22607cc) to head (b0cec2c).
⚠️ Report is 25 commits behind head on main.

Files with missing lines Patch % Lines
src/backend/base/langflow/services/auth/service.py 66.66% 135 Missing ⚠️
...t-view/chat-input/components/text-area-wrapper.tsx 0.00% 19 Missing ⚠️
...view/chat-header/hooks/use-session-has-messages.ts 0.00% 18 Missing ⚠️
src/lfx/src/lfx/base/mcp/util.py 0.00% 16 Missing ⚠️
src/lfx/src/lfx/services/auth/service.py 70.58% 15 Missing ⚠️
src/frontend/src/utils/reactflowUtils.ts 0.00% 10 Missing ⚠️
src/lfx/src/lfx/services/auth/exceptions.py 62.50% 9 Missing ⚠️
src/backend/base/langflow/services/auth/utils.py 89.18% 8 Missing ⚠️
...rComponent/components/inputFileComponent/index.tsx 0.00% 7 Missing ⚠️
...t-view/chat-header/components/session-selector.tsx 12.50% 7 Missing ⚠️
... and 24 more

❌ Your project status has failed because the head coverage (42.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   #11754      +/-   ##
==========================================
+ Coverage   35.02%   35.06%   +0.03%     
==========================================
  Files        1515     1522       +7     
  Lines       72567    73680    +1113     
  Branches    10934    11260     +326     
==========================================
+ Hits        25418    25835     +417     
- Misses      45755    46433     +678     
- Partials     1394     1412      +18     
Flag Coverage Δ
backend 55.74% <71.89%> (+0.17%) ⬆️
lfx 42.08% <73.36%> (+0.24%) ⬆️

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

Files with missing lines Coverage Δ
src/backend/base/langflow/api/v1/api_key.py 73.33% <100.00%> (ø)
src/backend/base/langflow/api/v1/endpoints.py 72.08% <100.00%> (ø)
src/backend/base/langflow/api/v1/mcp.py 72.57% <100.00%> (ø)
src/backend/base/langflow/api/v2/schemas.py 100.00% <100.00%> (ø)
...c/backend/base/langflow/services/auth/constants.py 100.00% <100.00%> (ø)
...kend/base/langflow/services/auth/mcp_encryption.py 73.07% <100.00%> (-1.93%) ⬇️
src/backend/base/langflow/services/deps.py 87.67% <100.00%> (+0.71%) ⬆️
...rc/backend/base/langflow/services/event_manager.py 75.42% <100.00%> (ø)
src/backend/base/langflow/services/factory.py 83.60% <100.00%> (+0.55%) ⬆️
...kend/base/langflow/services/variable/kubernetes.py 0.00% <ø> (ø)
... and 46 more

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

Base automatically changed from fix-header-tweaks to release-v1.8.0 February 12, 2026 14:40
@codeflash-ai codeflash-ai Bot closed this Feb 20, 2026
@codeflash-ai
Copy link
Copy Markdown
Contributor Author

codeflash-ai Bot commented Feb 20, 2026

This PR has been automatically closed because the original PR #11827 by vjgit96 was closed.

Base automatically changed from release-v1.8.0 to main February 20, 2026 18:56
@codeflash-ai codeflash-ai Bot deleted the codeflash/optimize-pr11753-2026-02-12T14.11.41 branch February 20, 2026 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

⚡️ codeflash Optimization PR opened by Codeflash AI community Pull Request from an external contributor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants