⚡️ Speed up function _build_model_config by 38% in PR #11807 (EJ/multi-api-support-merge-conflicts)#11808
Closed
codeflash-ai[bot] wants to merge 38 commits into
Closed
⚡️ Speed up function _build_model_config by 38% in PR #11807 (EJ/multi-api-support-merge-conflicts)#11808codeflash-ai[bot] wants to merge 38 commits into
_build_model_config by 38% in PR #11807 (EJ/multi-api-support-merge-conflicts)#11808codeflash-ai[bot] wants to merge 38 commits into
Conversation
Enhances provider variable handling by introducing a metadata structure for all required variables per provider, including support for providers with multiple required variables (e.g., IBM WatsonX). Updates backend API to return full variable info, adapts frontend to dynamically render and save multiple variables, and adds comprehensive tests for the new API response. Also updates static mappings and introduces a new React hook for fetching provider variable metadata.
Replaces per-variable auto-save with a batch save for all provider variables, improving UX and reducing API calls. Updates input handling to show masked values for secrets, disables save button until all required fields are filled, and provides clearer feedback for configured variables.
…w-ai/langflow into EJ/add-multi-api-support
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Centralize MODEL_PROVIDER_METADATA in model_metadata.py and update unified_models.py to import and use it. Refactor provider validation to accept all required variables as a dictionary, supporting providers with multiple required credentials. Simplify and generalize validation logic for all providers.
…w-ai/langflow into EJ/add-multi-api-support
Centralizes provider-specific parameter mappings in model_metadata.py and introduces get_provider_param_mapping for reuse. Updates unified_models.py to use this mapping, reducing duplication and improving maintainability for model class, API key, and other provider-specific parameters.
Replaces the API key-specific check with a more general configuration requirement, considering all required provider variables (not just secrets). Updates related UI logic and labels to reflect this broader configuration requirement.
Update logic to consider both secret and non-secret variables when determining enabled providers. Refactor to fetch all required provider variables, not just credentials, and ensure correct values are passed for validation. This improves accuracy for providers that require non-secret configuration variables.
Replaces provider-specific field toggling logic in starter project LanguageModelComponent definitions with a call to apply_provider_variable_config_to_build_config. This centralizes provider-specific configuration, improving maintainability and extensibility for new model providers.
Improve provider enablement checks and simplify model options handling. - Exclude the /models router from OpenAPI schema (include_in_schema=False). - Treat providers as enabled when credential variables exist (check non-empty values and strip whitespace) and avoid per-read API validation to reduce external latency; add skip_validation flag (default True) to _validate_and_get_enabled_providers to control validation behavior. - Consolidate credential collection logic (use env fallback, decrypt values when present) and downgrade parse/validation log noise by using debug level and safer JSON parsing. - Harden variable parsing in API endpoints: check for empty/None values, strip whitespace before JSON parsing, and handle parsing failures gracefully. - Add json import where needed and remove redundant local imports. - Always set build_config model input_types based on embedding vs language model types (ensures connection handles are enabled appropriately) and remove previous visibility-only logic. These changes aim to be more robust against empty/whitespace variable values, reduce unnecessary external validation calls, and simplify configuration logic.
The optimized code achieves a **37% speedup** by eliminating repeated allocations of the same constant data structures on every function call.
## Key Optimizations
**1. Module-level constant extraction**
The original code reconstructs the `model_classes` dictionary with 5 key-value pairs on every invocation. By moving this to module-level, the dictionary is allocated once at import time rather than 4,796+ times during execution. The line profiler shows the original spent ~11.8ms just building this dictionary across all calls (lines showing 1.7-2.7ms each for the dict construction).
**2. Metadata template with shallow copy**
Instead of constructing the metadata dictionary inline with 4 key-value pairs each time, the optimized version maintains a `_metadata_template` at module-level and performs a shallow `.copy()` operation. Dictionary copying in Python is highly optimized in C and faster than creating a new dict from scratch with multiple key assignments. The copy operation takes ~2.47ms total versus the original's inline construction which consumed more time across multiple lines.
**3. Why this works in Python**
Python dictionaries have allocation overhead - each `{}` literal triggers memory allocation, hash table setup, and key insertion operations. By reusing pre-allocated structures, we avoid this overhead. The shallow copy is efficient because it only copies references to the string keys/values, not the strings themselves.
## Test Case Performance
The optimization excels across all test scenarios:
- **Known providers**: Fast lookups from module-level dict (most common case)
- **Unknown providers**: Same performance as original for the default fallback
- **Large-scale tests**: The benefits compound - the 1000-iteration tests see cumulative savings from avoiding 1000+ dict constructions
- **Edge cases**: Empty strings, special characters, long names all benefit equally since the optimization is in constant allocation, not string handling
## Impact Assessment
Without `function_references`, we cannot determine call frequency in production, but this is a pure win optimization - it maintains identical behavior (same output structure, key ordering, and semantics) while being strictly faster. Any code path calling this function repeatedly (e.g., batch model configuration, API request handling loops) will see proportional improvements.
Base automatically changed from
EJ/multi-api-support-merge-conflicts
to
EJ/add-multi-api-support
February 18, 2026 17:31
Codecov Report❌ Patch coverage is ❌ Your project status has failed because the head coverage (42.17%) is below the target coverage (60.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #11808 +/- ##
==========================================
- Coverage 35.23% 32.17% -3.07%
==========================================
Files 1521 1521
Lines 72960 72740 -220
Branches 10938 10838 -100
==========================================
- Hits 25711 23407 -2304
- Misses 45855 47949 +2094
+ Partials 1394 1384 -10
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
Contributor
|
Closing automated codeflash PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
⚡️ This pull request contains optimizations for PR #11807
If you approve this dependent PR, these changes will be merged into the original PR branch
EJ/multi-api-support-merge-conflicts.📄 38% (0.38x) speedup for
_build_model_configinsrc/backend/base/langflow/agentic/flows/langflow_assistant.py⏱️ Runtime :
2.59 milliseconds→1.88 milliseconds(best of74runs)📝 Explanation and details
The optimized code achieves a 37% speedup by eliminating repeated allocations of the same constant data structures on every function call.
Key Optimizations
1. Module-level constant extraction
The original code reconstructs the
model_classesdictionary with 5 key-value pairs on every invocation. By moving this to module-level, the dictionary is allocated once at import time rather than 4,796+ times during execution. The line profiler shows the original spent ~11.8ms just building this dictionary across all calls (lines showing 1.7-2.7ms each for the dict construction).2. Metadata template with shallow copy
Instead of constructing the metadata dictionary inline with 4 key-value pairs each time, the optimized version maintains a
_metadata_templateat module-level and performs a shallow.copy()operation. Dictionary copying in Python is highly optimized in C and faster than creating a new dict from scratch with multiple key assignments. The copy operation takes ~2.47ms total versus the original's inline construction which consumed more time across multiple lines.3. Why this works in Python
Python dictionaries have allocation overhead - each
{}literal triggers memory allocation, hash table setup, and key insertion operations. By reusing pre-allocated structures, we avoid this overhead. The shallow copy is efficient because it only copies references to the string keys/values, not the strings themselves.Test Case Performance
The optimization excels across all test scenarios:
Impact Assessment
Without
function_references, we cannot determine call frequency in production, but this is a pure win optimization - it maintains identical behavior (same output structure, key ordering, and semantics) while being strictly faster. Any code path calling this function repeatedly (e.g., batch model configuration, API request handling loops) will see proportional improvements.✅ Correctness verification report:
⚙️ Click to see Existing Unit Tests
🌀 Click to see Generated Regression Tests
To edit these changes
git checkout codeflash/optimize-pr11807-2026-02-18T17.19.30and push.