Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion backend/services/nl2agent_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@

_LOCAL_KNOWLEDGE_TOOL_NAMES = frozenset({
"knowledge_base_search",
"ind_aidp_search",
})
_AIDP_KNOWLEDGE_TOOL_NAME = "aidp_search"

Expand Down
12 changes: 4 additions & 8 deletions backend/services/tool_configuration_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
AIDP_SERVER_URL,
AIDP_TENANT_ID,
DATA_PROCESS_SERVICE,
ENABLE_AIDP_KNOWLEDGE,
LOCAL_MCP_SERVER,
MCP_MANAGEMENT_API,
MCP_REQUEST_TIMEOUT_SECONDS,
Expand Down Expand Up @@ -83,18 +82,15 @@
"knowledge_base_search",
"aidp_search",
})
_INDEPENDENT_AIDP_SEARCH_TOOL = "ind_aidp_search"


def _get_deployment_user_selectability(
def _get_user_selectability(
tool_name: str,
default: bool,
) -> bool:
"""Return the deployment-controlled user selection state for a tool."""
"""Keep managed knowledge tools hidden from manual selection."""
if tool_name in _ALWAYS_HIDDEN_KNOWLEDGE_TOOLS:
return False
if tool_name == _INDEPENDENT_AIDP_SEARCH_TOOL:
return not ENABLE_AIDP_KNOWLEDGE
return default


Expand Down Expand Up @@ -309,7 +305,7 @@ def get_local_tools() -> List[ToolInfo]:
output_type=getattr(tool_class, 'output_type'),
category=getattr(tool_class, 'category'),
labels=getattr(tool_class, 'labels', None),
is_user_selectable=_get_deployment_user_selectability(
is_user_selectable=_get_user_selectability(
getattr(tool_class, 'name'),
getattr(tool_class, 'is_user_selectable', True),
),
Expand Down Expand Up @@ -920,7 +916,7 @@ async def list_all_tools(tenant_id: str, labels: Optional[List[str]] = None):
"inputs": inputs_str,
"category": tool.get("category"),
"labels": tool.get("labels", []),
"is_user_selectable": _get_deployment_user_selectability(
"is_user_selectable": _get_user_selectability(
tool_name,
tool.get("is_user_selectable", True),
),
Expand Down
10 changes: 10 additions & 0 deletions deploy/sql/migrations/v2.7.1_001_ind_aidp_search_selectable.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Keep knowledge_base_search hidden and independent AIDP search selectable.
UPDATE nexent.ag_tool_info_t
SET is_user_selectable = FALSE
WHERE name = 'knowledge_base_search'
AND is_user_selectable IS DISTINCT FROM FALSE;

UPDATE nexent.ag_tool_info_t
SET is_user_selectable = TRUE
WHERE name = 'ind_aidp_search'
AND is_user_selectable IS DISTINCT FROM TRUE;
1 change: 1 addition & 0 deletions sdk/nexent/core/tools/ind_aidp_search_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ class IndependentAidpSearchTool(Tool):
"""Search an independently configured AIDP knowledge-base scope."""

name = "ind_aidp_search"
is_user_selectable = True
description = (
"Searches independently configured AIDP knowledge bases with FusionSearch. "
"The configured knowledge bases are the default scope; callers may provide a "
Expand Down
3 changes: 2 additions & 1 deletion test/backend/services/test_nl2agent_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -849,7 +849,7 @@ async def test_search_installed_resources_covers_visible_tools_and_skills(mocker
@pytest.mark.parametrize(
("enable_aidp_knowledge", "expected_knowledge_tools"),
[
(True, {"aidp_search"}),
(True, {"aidp_search", "ind_aidp_search"}),
(False, {"knowledge_base_search", "ind_aidp_search"}),
],
)
Expand All @@ -868,6 +868,7 @@ async def test_installed_resource_catalog_filters_knowledge_tools_by_deployment(
"description": "Knowledge search",
"source": "local",
"is_available": True,
"is_user_selectable": name == "ind_aidp_search",
}
for tool_id, name in enumerate(
(
Expand Down
58 changes: 8 additions & 50 deletions test/backend/services/test_tool_configuration_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -4340,34 +4340,10 @@ def __init__(self):
inputs = json.loads(result[0].inputs)
assert inputs == {"query": "string"}

@pytest.mark.parametrize(
("enable_aidp_knowledge", "expected_selectability"),
[
(
True,
{
"knowledge_base_search": False,
"aidp_search": False,
"ind_aidp_search": False,
},
),
(
False,
{
"knowledge_base_search": False,
"aidp_search": False,
"ind_aidp_search": True,
},
),
],
)
@patch('backend.services.tool_configuration_service.get_local_tools_classes')
def test_get_local_tools_applies_knowledge_tool_selectability_by_deployment(
def test_get_local_tools_keeps_independent_aidp_search_selectable(
self,
mock_get_classes,
monkeypatch,
enable_aidp_knowledge,
expected_selectability,
):
class KnowledgeTool:
name = "knowledge_base_search"
Expand All @@ -4391,36 +4367,24 @@ class IndependentAidpTool(KnowledgeTool):
AidpTool,
IndependentAidpTool,
]
monkeypatch.setattr(
_tool_cfg_service,
"ENABLE_AIDP_KNOWLEDGE",
enable_aidp_knowledge,
)

result = _tool_cfg_service.get_local_tools()

assert {
tool.name: tool.is_user_selectable
for tool in result
} == expected_selectability
} == {
"knowledge_base_search": False,
"aidp_search": False,
"ind_aidp_search": True,
}

@pytest.mark.parametrize(
("enable_aidp_knowledge", "expected_selectability"),
[
(True, [False, False, False]),
(False, [False, False, True]),
],
)
@patch('backend.services.tool_configuration_service.get_local_tools_description_zh')
@patch('backend.services.tool_configuration_service.query_all_tools')
@pytest.mark.asyncio
async def test_list_all_tools_applies_deployment_selectability_to_stale_records(
async def test_list_all_tools_preserves_independent_aidp_search_selectability(
self,
mock_query,
mock_get_descriptions,
monkeypatch,
enable_aidp_knowledge,
expected_selectability,
):
mock_query.return_value = [
{
Expand All @@ -4441,15 +4405,9 @@ async def test_list_all_tools_applies_deployment_selectability_to_stale_records(
)
]
mock_get_descriptions.return_value = {}
monkeypatch.setattr(
_tool_cfg_service,
"ENABLE_AIDP_KNOWLEDGE",
enable_aidp_knowledge,
)

result = await _tool_cfg_service.list_all_tools("tenant-a")

assert [tool["is_user_selectable"] for tool in result] == expected_selectability
assert [tool["is_user_selectable"] for tool in result] == [False, False, True]

@patch('backend.services.tool_configuration_service.get_local_tools_description_zh')
@patch('backend.services.tool_configuration_service.query_all_tools')
Expand Down
Loading