diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml index c70ac0b..ed4bade 100644 --- a/.github/workflows/integration_test.yml +++ b/.github/workflows/integration_test.yml @@ -192,7 +192,7 @@ jobs: CREDS: "alice:alice" run: | sleep 300 - TASK=$(curl -X POST -u "$CREDS" -H "oCS-APIRequest: true" -H "Content-type: application/json" http://localhost:8080/ocs/v2.php/taskprocessing/schedule?format=json --data-raw '{"input": {"input": "Search youtube for videos about Nextcloud", "confirmation":1, "conversation_token": ""},"type":"core:contextagent:interaction", "appId": "test", "customId": ""}') + TASK=$(curl -X POST -u "$CREDS" -H "oCS-APIRequest: true" -H "Content-type: application/json" http://localhost:8080/ocs/v2.php/taskprocessing/schedule?format=json --data-raw '{"input": {"input": "List the files I have in Nextcloud", "confirmation":1, "conversation_token": ""},"type":"core:contextagent:interaction", "appId": "test", "customId": ""}') echo $TASK TASK_ID=$(echo $TASK | jq '.ocs.data.task.id') NEXT_WAIT_TIME=0 @@ -209,8 +209,7 @@ jobs: [ "$TASK_STATUS" == '"STATUS_SUCCESSFUL"' ] echo $TASK | jq '.ocs.data.task.output.output' echo $TASK | jq '.ocs.data.task.output.sources' - echo $TASK | jq '.ocs.data.task.output.sources' | grep -q 'youtube_search' - echo $TASK | jq '.ocs.data.task.output.output' | grep -q 'Nextcloud' + echo $TASK | jq '.ocs.data.task.output.sources' | grep -q 'get_folder_tree' - name: Show nextcloud logs if: always() diff --git a/ex_app/lib/all_tools/files.py b/ex_app/lib/all_tools/files.py index 5f68b62..304a38c 100644 --- a/ex_app/lib/all_tools/files.py +++ b/ex_app/lib/all_tools/files.py @@ -54,7 +54,7 @@ async def get_file_content_by_file_link(file_url: str): @safe_tool async def get_folder_tree(depth: int): """ - Get the folder tree of the user + Get the folder tree of the user (lists the files the user has in Nextcloud Files) :param depth: the depth of the returned folder tree :return: """ diff --git a/ex_app/lib/all_tools/search.py b/ex_app/lib/all_tools/search.py new file mode 100644 index 0000000..9ee7def --- /dev/null +++ b/ex_app/lib/all_tools/search.py @@ -0,0 +1,37 @@ +# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: AGPL-3.0-or-later +import json + +from langchain_core.tools import tool +from nc_py_api import AsyncNextcloudApp + +from ex_app.lib.all_tools.lib.decorator import safe_tool + +async def get_tools(nc: AsyncNextcloudApp): + tools = [] + providers = await nc.ocs('GET', '/ocs/v2.php/search/providers') + + for provider in providers: + def make_tool(p): + async def tool(search_query: dict[str, str]): + results = await nc.ocs('GET', f"/ocs/v2.php/search/providers/{p['id']}/search", params=search_query) + return json.dumps(results['entries']) + return tool + + tool_func = make_tool(provider) + tool_func.__name__ = "search_" + provider['name'].lower() + tool_func.__doc__ = ( + f"Searches {provider['name']} in Nextcloud.\n" + f":param search_query: A mapping of filter names to filter values to use for the search. " + f"Choose filters from {json.dumps(provider['filters'])}. " + 'For example: {"term": "hans", ...}\n' + ) + tools.append(tool(safe_tool(tool_func))) + + return tools + +def get_category_name(): + return "Unified Search" + +async def is_available(nc: AsyncNextcloudApp): + return True