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
2 changes: 1 addition & 1 deletion ex_app/lib/all_tools/audio2text.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ async def get_tools(nc: Nextcloud):
@safe_tool
def transcribe_file(file_url: str) -> str:
"""
Transcribe a media file stored inside the nextcloud
Transcribe a media file stored inside Nextcloud
:param file_url: The file URL to the media file in nextcloud (The user can input this using the smart picker for example)
:return: the transcription result
"""
Expand Down
2 changes: 1 addition & 1 deletion ex_app/lib/all_tools/contacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def find_person_in_contacts(name: str) -> list[dict[str, typing.Any]]:
@safe_tool
def find_details_of_current_user() -> dict[str, typing.Any]:
"""
Find the user's personal information
Find the current user's personal information
:return: a dictionary with the person's personal information
"""

Expand Down
2 changes: 1 addition & 1 deletion ex_app/lib/all_tools/context_chat.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ async def get_tools(nc: Nextcloud):
@safe_tool
def ask_context_chat(question: str) -> str:
"""
Ask the context chat oracle, which knows all of the user's documents, a question about them
Ask the context chat oracle a question about the user's documents. It knows the contents of all of the users documents.
:param question: The question to ask
:return: the answer from context chat
"""
Expand Down
26 changes: 9 additions & 17 deletions ex_app/lib/all_tools/deck.py
Original file line number Diff line number Diff line change
@@ -1,27 +1,19 @@
# SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: AGPL-3.0-or-later
from datetime import datetime, timezone, timedelta
from time import sleep
from typing import Optional

import pytz
from langchain_core.tools import tool
from nc_py_api import Nextcloud
from nc_py_api.ex_app import LogLvl
import xml.etree.ElementTree as ET
import vobject

from ex_app.lib.all_tools.lib.decorator import safe_tool, dangerous_tool
from ex_app.lib.logger import log


async def get_tools(nc: Nextcloud):

@tool
@safe_tool
def list_decks():
def list_boards():
"""
List all existing kanban decks with their available info
List all existing kanban boards available in the Nextcloud Deck app for the current user with their available info
:return: a dictionary with all decks of the user
"""

Expand All @@ -35,17 +27,17 @@ def list_decks():

@tool
@dangerous_tool
def add_card(deck_id: int, stack_id: int, title: str):
def add_card(board_id: int, stack_id: int, title: str):
"""
Create a new card in a list of a kanban deck.
When using this tool, you need to specify in which deck and map the card should be created.
:param deck_id: the id of the deck the card should be created in, obtainable with list_decks
:param stack_id: the id of the stack the card should be created in, obtainable with list_decks
Create a new card in a list of a kanban board in the Nextcloud Deck app.
When using this tool, you need to specify in which board and map the card should be created.
:param board_id: the id of the board the card should be created in, obtainable with list_boards
:param stack_id: the id of the stack the card should be created in, obtainable with list_boards
:param title: The title of the card
:return: bool
"""

response = nc._session._create_adapter(True).request('POST', f"{nc.app_cfg.endpoint}/index.php/apps/deck/api/v1.0//boards/{deck_id}/stacks/{stack_id}/cards", headers={
response = nc._session._create_adapter(True).request('POST', f"{nc.app_cfg.endpoint}/index.php/apps/deck/api/v1.0/boards/{board_id}/stacks/{stack_id}/cards", headers={
"Content-Type": "application/json",
}, json={
'title': title,
Expand All @@ -58,7 +50,7 @@ def add_card(deck_id: int, stack_id: int, title: str):
return True

return [
list_decks,
list_boards,
add_card
]

Expand Down
4 changes: 2 additions & 2 deletions ex_app/lib/all_tools/doc-gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ async def get_tools(nc: Nextcloud):
@safe_tool
def generate_document(input: str, format: str) -> str:
"""
Generate a document with the input string as description.
:param text: the instructions for the document
Generate an office document based on a description of what it should contain
:param input: the instructions for what the document should contain
:param format: the format of the generated file, allowed values are "text document", "pdf", "spreadsheet", "excel spreadsheet" and "slides"
:return: a download link to the generated document
"""
Expand Down
26 changes: 25 additions & 1 deletion ex_app/lib/all_tools/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
from langchain_core.tools import tool
from nc_py_api import Nextcloud
import niquests

from typing import Optional
from ex_app.lib.all_tools.lib.files import get_file_id_from_file_url

from ex_app.lib.all_tools.lib.decorator import safe_tool, dangerous_tool

Expand All @@ -27,6 +28,28 @@ def get_file_content(file_path: str):

return response.text

@tool
@safe_tool
def get_file_content_by_file_link(file_url: str):
"""
Get the content of a file given an internal Nextcloud link (e.g., https://host/index.php/f/12345)
:param file_url: the internal file URL
:return: text content of the file
"""

file_id = get_file_id_from_file_url(file_url)
# Generate a direct download link using the fileId
info = nc.ocs('POST', '/ocs/v2.php/apps/dav/api/v1/direct', json={'fileId': file_id}, response_type='json')
download_url = info.get('ocs', {}).get('data', {}).get('url', None)

if not download_url:
raise Exception('Could not generate download URL from file id')

# Download the file from the direct download URL
response = niquests.get(download_url)

return response.text

@tool
@safe_tool
def get_folder_tree(depth: int):
Expand Down Expand Up @@ -56,6 +79,7 @@ def create_public_sharing_link(path: str):

return [
get_file_content,
get_file_content_by_file_link,
get_folder_tree,
create_public_sharing_link,
]
Expand Down
3 changes: 1 addition & 2 deletions ex_app/lib/all_tools/image_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from langchain_core.tools import tool
from nc_py_api import Nextcloud

from ex_app.lib.all_tools.lib.files import get_file_id_from_file_url
from ex_app.lib.all_tools.lib.task_processing import run_task
from ex_app.lib.all_tools.lib.decorator import safe_tool

Expand All @@ -14,7 +13,7 @@ async def get_tools(nc: Nextcloud):
@safe_tool
def generate_image(input: str) -> str:
"""
Generate an image with the input string as description
Generate an image using AI from a text description input
:param text: the instructions for the image generation
:return: a download link to the generated image
"""
Expand Down
6 changes: 3 additions & 3 deletions ex_app/lib/all_tools/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ async def get_tools(nc: Nextcloud):
@dangerous_tool
def send_email(subject: str, body: str, account_id: int, from_email: str, to_emails: list[str]):
"""
Send an email to a list of emails
Send an email to a list of email addresses
:param subject: The subject of the email
:param body: The body of the email
:param account_id: The id of the account to send from, obtainable via get_mail_account_list
:param to_emails: The emails to send
:param to_emails: The email addresses to send the message to
"""
i = 0
body_with_ai_note = f"{body}\n\n---\n\nThis email was sent by Nextcloud AI Assistant."
Expand All @@ -47,7 +47,7 @@ def send_email(subject: str, body: str, account_id: int, from_email: str, to_ema
@safe_tool
def get_mail_account_list():
"""
Lists all available email accounts including their account id
Lists all available email accounts of the current user including their account id
:param subject: The subject of the email
:param body: The body of the email
:param account_id: The id of the account to send from
Expand Down
8 changes: 4 additions & 4 deletions ex_app/lib/all_tools/talk.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async def get_tools(nc: Nextcloud):
@safe_tool
def list_talk_conversations():
"""
List all conversations in talk
List all conversations of the current user in the Nextcloud Talk app
:return: returns a list of conversation names, e.g. ["Conversation 1", "Conversation 2"]
"""
conversations = nc.talk.get_user_conversations()
Expand All @@ -23,7 +23,7 @@ def list_talk_conversations():
@dangerous_tool
def create_public_conversation(conversation_name: str) -> str:
"""
Create a new talk conversation
Create a new conversation in the Nextcloud Talk app
:param conversation_name: The name of the conversation to create
:return: The URL of the new conversation
"""
Expand All @@ -36,7 +36,7 @@ def create_public_conversation(conversation_name: str) -> str:
@dangerous_tool
def send_message_to_conversation(conversation_name: str, message: str):
"""
List all conversations in talk
Send a message to a conversation in the Nextcloud talk app
:param message: The message to send
:param conversation_name: The name of the conversation to send a message to
:return:
Expand All @@ -52,7 +52,7 @@ def send_message_to_conversation(conversation_name: str, message: str):
@safe_tool
def list_messages_in_conversation(conversation_name: str, n_messages: int = 30):
"""
List messages of a conversation in talk
List messages of a conversation in the Nextcloud Talk app
:param conversation_name: The name of the conversation to list messages of (can only be one conversation per Tool call, obtainable via list_talk_conversations)
:param n_messages: The number of messages to receive
:return: A list of messages
Expand Down
Loading