Skip to content

Commit 480a9e6

Browse files
authored
Merge pull request #138 from nextcloud/feat/find-userid
Add find user tool
2 parents 12879e2 + 0f45f19 commit 480a9e6

3 files changed

Lines changed: 27 additions & 5 deletions

File tree

ex_app/lib/agent.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ async def call_model(
133133
system_prompt_text += "Use the list_calendars tool to check which calendars exist.\nIf an item should be added to a list, check list_calendars for a fitting calendar and add the item as a task there.\n"
134134
if tool_enabled("find_person_in_contacts"):
135135
system_prompt_text += "Use the find_person_in_contacts tool to find a person's email address and location.\n"
136+
if tool_enabled("find_person_in_users"):
137+
system_prompt_text += "Use the find_person_in_users tool to find a person's userId and user details.\n"
136138
if tool_enabled("find_details_of_current_user"):
137139
system_prompt_text += "Use the find_details_of_current_user tool to find the current user's location.\n"
138140

ex_app/lib/all_tools/contacts.py

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
22
# SPDX-License-Identifier: AGPL-3.0-or-later
3+
import json
34
import typing
45

56
from langchain_core.tools import tool
@@ -11,6 +12,24 @@
1112

1213

1314
async def get_tools(nc: AsyncNextcloudApp):
15+
@tool
16+
@safe_tool
17+
async def find_person_in_users(search_term: str):
18+
"""
19+
Search for users
20+
:param search_term: The search term to find the user by. Use this to find a user's ID
21+
Returns:
22+
"""
23+
users = await nc.ocs('GET', '/ocs/v2.php/apps/files_sharing/api/v1/sharees', params={
24+
'search': search_term,
25+
'shareType': 0,
26+
'itemType': 'user',
27+
})
28+
dict = {}
29+
for user in users.get('exact', {}).get('users', []) + users.get('users', []):
30+
dict[user.get('label')] = user.get('value', {}).get('shareWith')
31+
return json.dumps(dict)
32+
1433
@tool
1534
@safe_tool
1635
async def find_person_in_contacts(name: str) -> list[dict[str, typing.Any]]:
@@ -19,11 +38,10 @@ async def find_person_in_contacts(name: str) -> list[dict[str, typing.Any]]:
1938
:param name: the name to search for
2039
:return: a dictionary with the person's email, phone and address
2140
"""
22-
username = nc._session.user
41+
username = await nc._session.user
2342
response = await nc._session._create_adapter(True).request('PROPFIND', f"{nc.app_cfg.endpoint}/remote.php/dav/addressbooks/users/{username}/", headers={
2443
"Content-Type": "application/xml; charset=utf-8",
2544
})
26-
print(response.text)
2745
namespace = {"DAV": "DAV:"} # Define the namespace
2846
root = ET.fromstring(response.text)
2947
hrefs = root.findall(".//DAV:href", namespace)
@@ -53,7 +71,7 @@ async def find_person_in_contacts(name: str) -> list[dict[str, typing.Any]]:
5371
"Content-Type": "application/xml; charset=utf-8",
5472
"Depth": "1",
5573
}, content=xml_body)
56-
print(response.text)
74+
5775
if response.status_code != 207: # Multi-Status
5876
raise Exception(f"Error: {response.status_code} - {response.reason_phrase}")
5977

@@ -88,7 +106,9 @@ async def find_details_of_current_user() -> dict[str, typing.Any]:
88106

89107

90108
return [
91-
find_person_in_contacts, find_details_of_current_user
109+
find_person_in_users,
110+
find_person_in_contacts,
111+
find_details_of_current_user
92112
]
93113

94114
def get_category_name():

ex_app/lib/all_tools/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async def tool(search_query: dict[str, str]):
2424
tool_func.__doc__ = (
2525
f"Searches {provider['name']} in Nextcloud.\n"
2626
f":param search_query: A mapping of filter names to filter values to use for the search. "
27-
f"Choose filters from {json.dumps(provider['filters'])}. "
27+
f"Choose filters from {json.dumps(provider['filters'])}. (The 'person' filter, if available, takes a userID. Use find_person_in_users to obtain it.)"
2828
'For example: {"term": "hans", ...}\n'
2929
)
3030
tools.append(tool(safe_tool(tool_func)))

0 commit comments

Comments
 (0)