diff --git a/backend/services/nl2agent_service.py b/backend/services/nl2agent_service.py index 6e5ce73ee9..d945c3753d 100644 --- a/backend/services/nl2agent_service.py +++ b/backend/services/nl2agent_service.py @@ -77,7 +77,6 @@ _LOCAL_KNOWLEDGE_TOOL_NAMES = frozenset({ "knowledge_base_search", - "ind_aidp_search", }) _AIDP_KNOWLEDGE_TOOL_NAME = "aidp_search" diff --git a/backend/services/tool_configuration_service.py b/backend/services/tool_configuration_service.py index 38f0b12743..f2c366e07f 100644 --- a/backend/services/tool_configuration_service.py +++ b/backend/services/tool_configuration_service.py @@ -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, @@ -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 @@ -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), ), @@ -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), ), diff --git a/deploy/sql/migrations/v2.7.1_001_ind_aidp_search_selectable.sql b/deploy/sql/migrations/v2.7.1_001_ind_aidp_search_selectable.sql new file mode 100644 index 0000000000..a16ad4835b --- /dev/null +++ b/deploy/sql/migrations/v2.7.1_001_ind_aidp_search_selectable.sql @@ -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; diff --git a/sdk/nexent/core/tools/ind_aidp_search_tool.py b/sdk/nexent/core/tools/ind_aidp_search_tool.py index 2a1409bb77..2dfb55a759 100644 --- a/sdk/nexent/core/tools/ind_aidp_search_tool.py +++ b/sdk/nexent/core/tools/ind_aidp_search_tool.py @@ -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 " diff --git a/test/backend/services/test_nl2agent_service.py b/test/backend/services/test_nl2agent_service.py index 2782b4a886..a2dfe6eb5c 100644 --- a/test/backend/services/test_nl2agent_service.py +++ b/test/backend/services/test_nl2agent_service.py @@ -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"}), ], ) @@ -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( ( diff --git a/test/backend/services/test_tool_configuration_service.py b/test/backend/services/test_tool_configuration_service.py index 66f10615e1..2a1e373105 100644 --- a/test/backend/services/test_tool_configuration_service.py +++ b/test/backend/services/test_tool_configuration_service.py @@ -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" @@ -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 = [ { @@ -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')