-
Notifications
You must be signed in to change notification settings - Fork 5.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add tool filter #6951
base: main
Are you sure you want to change the base?
feat: add tool filter #6951
Conversation
…(`feat-add-tool-filter`) Here's the optimized version of the Python program. In this revision, I applied the Walrus operator (`:=`) to avoid an additional lookup for the "tags" key in the dictionary, making the loop condition more direct and slightly improving performance.
|
||
def _extract_tools_tags(self, tools_metadata: list[dict]) -> list[str]: | ||
"""Extract the first tag from each tool's metadata.""" | ||
return [tool["tags"][0] for tool in tools_metadata if tool["tags"]] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return [tool["tags"][0] for tool in tools_metadata if tool["tags"]] | |
return [tags[0] for tool in tools_metadata if (tags := tool["tags"])] |
⚡️ Codeflash found optimizations for this PR📄 19% (0.19x) speedup for
|
Test | Status |
---|---|
⚙️ Existing Unit Tests | 🔘 None Found |
🌀 Generated Regression Tests | ✅ 29 Passed |
⏪ Replay Tests | 🔘 None Found |
🔎 Concolic Coverage Tests | 🔘 None Found |
📊 Tests Coverage | undefined |
🌀 Generated Regression Tests Details
from __future__ import annotations
from copy import deepcopy
from typing import Any
import nanoid
# imports
import pytest # used for our unit tests
from langflow.custom.custom_component.component import Component
from langflow.custom.custom_component.custom_component import CustomComponent
from langflow.events.event_manager import EventManager
from langflow.graph.edge.schema import EdgeData
from langflow.inputs.inputs import InputTypes
from langflow.services.tracing.schema import Log
from langflow.template.field.base import Output
from langflow.utils.async_helpers import run_until_complete
# unit tests
def test_basic_functionality():
component = Component()
codeflash_output = component._extract_tools_tags([{"tags": ["tag1"]}])
codeflash_output = component._extract_tools_tags([{"tags": ["tag1"]}, {"tags": ["tag2"]}])
codeflash_output = component._extract_tools_tags([{"tags": ["tag1", "tag2"]}, {"tags": ["tag3", "tag4"]}])
def test_edge_cases():
component = Component()
codeflash_output = component._extract_tools_tags([])
codeflash_output = component._extract_tools_tags([{"tags": []}])
codeflash_output = component._extract_tools_tags([{}])
codeflash_output = component._extract_tools_tags([{"tags": ["tag1"]}, {"tags": []}, {}, {"tags": ["tag2"]}])
def test_complex_cases():
component = Component()
codeflash_output = component._extract_tools_tags([{"tags": [["nested_tag"]]}])
codeflash_output = component._extract_tools_tags([{"tags": [123]}])
codeflash_output = component._extract_tools_tags([{"tags": ["tag1", 123]}, {"tags": [456, "tag2"]}])
def test_large_scale_cases():
component = Component()
codeflash_output = component._extract_tools_tags([{"tags": ["tag" + str(i)]} for i in range(1000)])
codeflash_output = component._extract_tools_tags([{"tags": ["tag" + str(i) for i in range(1000)]}])
def test_unusual_inputs():
component = Component()
with pytest.raises(TypeError):
component._extract_tools_tags([{"tags": ["tag1"]}, "not_a_dict", {"tags": ["tag2"]}])
with pytest.raises(TypeError):
component._extract_tools_tags([{"tags": ["tag1"]}, 123, {"tags": ["tag2"]}, None])
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
from __future__ import annotations
from copy import deepcopy
from typing import Any
import nanoid
# imports
import pytest # used for our unit tests
from langflow.custom.custom_component.component import Component
from langflow.custom.custom_component.custom_component import CustomComponent
from langflow.events.event_manager import EventManager
from langflow.graph.edge.schema import EdgeData
from langflow.inputs.inputs import InputTypes
from langflow.services.tracing.schema import Log
from langflow.template.field.base import Output
from langflow.utils.async_helpers import run_until_complete
# unit tests
@pytest.fixture
def component():
return Component()
def test_single_tool_with_tags(component):
tools_metadata = [{"tags": ["tag1", "tag2"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_multiple_tools_with_tags(component):
tools_metadata = [{"tags": ["tag1", "tag2"]}, {"tags": ["tagA", "tagB"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_empty_list(component):
tools_metadata = []
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_tool_without_tags(component):
tools_metadata = [{"tags": []}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_mixed_tags_and_no_tags(component):
tools_metadata = [{"tags": ["tag1"]}, {"tags": []}, {"tags": ["tag2"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_nested_tags(component):
tools_metadata = [{"tags": [["nested_tag1"]]}, {"tags": ["tag2"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_tags_with_special_characters(component):
tools_metadata = [{"tags": ["tag-1", "tag_2"]}, {"tags": ["tag@3", "tag#4"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_large_number_of_tools(component):
tools_metadata = [{"tags": ["tag1"]}] * 1000
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_large_number_of_tags_in_a_tool(component):
tools_metadata = [{"tags": ["tag" + str(i) for i in range(1000)]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_combination_of_large_number_of_tools_and_tags(component):
tools_metadata = [{"tags": ["tag" + str(i) for i in range(100)]} for _ in range(1000)]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_non_dictionary_elements(component):
tools_metadata = ["not_a_dict"]
with pytest.raises(TypeError):
component._extract_tools_tags(tools_metadata)
def test_single_tool_with_single_tag(component):
tools_metadata = [{"tags": ["single_tag"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_single_tool_with_maximum_length_tag(component):
tools_metadata = [{"tags": ["a" * 1000]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_tools_with_empty_strings_as_tags(component):
tools_metadata = [{"tags": [""]}, {"tags": ["tag1"]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_extremely_large_data_set(component):
tools_metadata = [{"tags": ["tag" + str(i) for i in range(1000)]} for _ in range(1000)]
codeflash_output = component._extract_tools_tags(tools_metadata)
def test_high_complexity_tags(component):
tools_metadata = [{"tags": ["tag" + "a" * i for i in range(1000)]}]
codeflash_output = component._extract_tools_tags(tools_metadata)
# codeflash_output is used to check that the output of the original code is the same as that of the optimized code.
To test or edit this optimization locally git merge codeflash/optimize-pr6951-2025-03-06T16.47.32
CodSpeed Performance ReportMerging #6951 will improve performances by 71.24%Comparing Summary
Benchmarks breakdown
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PR Overview
This pull request enhances tool metadata management by introducing a new status field and dynamic filtering of tools based on their status, as well as methods to manage a list of enabled tools.
- Add a boolean "status" field to tool metadata to indicate tool activity.
- Introduce class-level methods (set_enabled_tools and get_enabled_tools) and a filtering mechanism (_filter_tools_by_status) in custom components.
- Update tool metadata processing in component_tool.py to filter out tools with inactive status.
Reviewed Changes
File | Description |
---|---|
src/backend/base/langflow/custom/custom_component/component.py | New methods for managing enabled tools and status-based filtering. |
src/backend/base/langflow/base/tools/constants.py | Added new "status" metadata field to tools constants. |
src/backend/base/langflow/base/tools/component_tool.py | Updated metadata filtering logic based on tool status. |
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
src/backend/base/langflow/base/tools/component_tool.py:311
- Using the '|' operator in isinstance() checks is not supported. Replace it with a tuple: isinstance(tool, (StructuredTool, BaseTool)).
if isinstance(tool, StructuredTool | BaseTool) and tool.tags:
src/backend/base/langflow/custom/custom_component/component.py:1112
- [nitpick] The nested conditional logic in _build_tools_metadata_input is somewhat complex; consider refactoring or adding inline comments to improve readability and maintainability.
if self.check_for_tool_tag_change(old_tags, new_tags):
"display_name": "Status", | ||
"type": "boolean", | ||
"description": "Indicates whether the tool is currently active. Set to True to activate this tool.", | ||
"default": "False", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value for the 'status' field is set as a string "False" even though the type is boolean. Replace it with the boolean value False.
"default": "False", | |
"default": False, |
Copilot is powered by AI, so mistakes are possible. Review output carefully before use.
Merge only after #6935 |
8ba5844
to
43d2511
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We definitely need tests for these.
"display_name": "Status", | ||
"type": "boolean", | ||
"description": "Indicates whether the tool is currently active. Set to True to activate this tool.", | ||
"default": "False", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be set to True
by default instead? I think it shouldn't have quotes either.
@@ -35,6 +35,14 @@ | |||
"edit_mode": EditMode.INLINE, | |||
"hidden": True, | |||
}, | |||
{ | |||
"name": "status", | |||
"display_name": "Status", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need a more descriptive name for this. Enabled
or Active
.. something like that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of status right?
Co-authored-by: Copilot <[email protected]>
aa3191f
to
98adfc9
Compare
This pull request includes changes to enhance the tool metadata management by introducing a status flag and enabling dynamic filtering of tools based on their status. The most important changes include the addition of a status field to the tool metadata, modifications to filter tools based on their status, and the introduction of methods to manage the list of enabled tools.
Enhancements to tool metadata management:
src/backend/base/langflow/base/tools/constants.py
: Added a new metadata fieldstatus
to indicate whether a tool is active.Dynamic filtering of tools:
src/backend/base/langflow/base/tools/component_tool.py
: Updatedupdate_tools_metadata
method to filter tools based on their status and return only active tools. [1] [2]Management of enabled tools:
src/backend/base/langflow/custom/custom_component/component.py
: Introduced_enabled_tools
class variable and methodsset_enabled_tools
andget_enabled_tools
to manage the list of enabled tools. [1] [2]src/backend/base/langflow/custom/custom_component/component.py
: Added_filter_tools_by_status
method to filter tools based on their status and the list of enabled tools.src/backend/base/langflow/custom/custom_component/component.py
: Implementedto_toolkit
method to convert components to a list of tools, incorporating the new status-based filtering logic.