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/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ async def call_model(
if tool_enabled("find_person_in_users"):
system_prompt_text += "Use the find_person_in_users tool to find a person's userId and user details.\n"
if tool_enabled("find_details_of_current_user"):
system_prompt_text += "Use the find_details_of_current_user tool to find the current user's location.\n"
system_prompt_text += "Use the find_details_of_current_user tool to find the current user's location and timezone.\n"
if tool_enabled("list_mails"):
system_prompt_text += "Always check for the mail account id before requesting a folder list.\n"

Expand Down
21 changes: 13 additions & 8 deletions ex_app/lib/all_tools/assignments.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# SPDX-License-Identifier: AGPL-3.0-or-later
import datetime

import pytz
from langchain_core.tools import tool
from nc_py_api import AsyncNextcloudApp

Expand All @@ -12,17 +13,18 @@ async def get_tools(nc: AsyncNextcloudApp):

@tool
@dangerous_tool
async def create_scheduled_task(title: str, prompt: str, recurrence_rule: str, starts_at: None|str = None):
async def create_scheduled_task(title: str, prompt: str, recurrence_rule: str, timezone: str|None = None, starts_at: None|str = None):
"""
Create a recurring Scheduled Task for the assistant that will be carried out autonomously.
Create a Scheduled Task for the assistant that will be carried out autonomously.
The user will still have to approve sensitive actions.
For example, the user could ask to transcribe new files in a certain folder every hour. Then the
prompt argument for this tool would be "Transcribe new files in folder /Audio" and the recurrence_rule would be "FREQ=HOURLY".
After having created the Scheduled Task, let the user know that the Scheduled Task will run in a newly created chat session.
:param title: A title for the Scheduled Task, e.g. "Transcribe audio files" -- This is only for the user's reference and has no effect on the execution of the Scheduled Task.
:param prompt: The instructions for the AI carrying out the Scheduled Task
:param recurrence_rule: An RRule compliant with RFC 5545 that defines the recurrence rule for the Scheduled Task. For example "FREQ=DAILY;INTERVAL=1" to run the Scheduled Task every day.
:param starts_at: A date time string in ISO 8601 format that defines when the Scheduled Task should start. For example "2025-01-01T09:00:00Z". If not provided, the Scheduled Task will start immediately.
:param recurrence_rule: An RRule compliant with RFC 5545 that defines the recurrence rule for the Scheduled Task. For example "FREQ=DAILY;INTERVAL=1" to run the Scheduled Task every day, an empty string as the recurrence_rule means the task does not repeat.
:param starts_at: A date time string in ISO 8601 format that defines when the Scheduled Task should start. For example "2025-01-01T09:00:00Z". If not provided, the Scheduled Task will start immediately. Make sure to use the user's timezone for this, obtainable with find_details_of_current_user
:param timezone: Timezone (e.g., 'America/New_York') defaults to the user's current time zone
:return:
"""

Expand All @@ -31,6 +33,7 @@ async def create_scheduled_task(title: str, prompt: str, recurrence_rule: str, s
'prompt': prompt,
'recurrence': recurrence_rule,
'startsAt': int(datetime.datetime.fromisoformat(starts_at.replace('Z', '+00:00')).timestamp()) if starts_at is not None else datetime.datetime.now(datetime.UTC).timestamp(),
'timezone': pytz.timezone(timezone).zone if timezone is not None else None
})

return True
Expand All @@ -39,20 +42,21 @@ async def create_scheduled_task(title: str, prompt: str, recurrence_rule: str, s
@safe_tool
async def list_scheduled_tasks():
"""
List all recurring assistant Scheduled Tasks by the current user.
List all assistant Scheduled Tasks by the current user.
:return:
"""

return await nc.ocs('GET', f'/ocs/v2.php/apps/assistant/assignments')

@tool
@dangerous_tool
async def update_scheduled_task(id: int, prompt: None|str = None, recurrence_rule: None|str = None, starts_at: None|str = None):
async def update_scheduled_task(id: int, prompt: None|str = None, recurrence_rule: None|str = None, timezone: str|None = None, starts_at: None|str = None):
"""
Update a recurring assistant Scheduled Task
Update a assistant Scheduled Task
:param id: The ID of the Scheduled Task to update, you can obtain this from the list_scheduled_tasks tool
:param prompt: The instructions for the AI carrying out the Scheduled Task. Pass `None` to leave this unchanged.
:param recurrence_rule: An RRule compliant with RFC 5545 that defines the recurrence rule for the Scheduled Task. For example "FREQ=DAILY;INTERVAL=1" to run the Scheduled Task every day. Pass `None` to leave this unchanged.
:param recurrence_rule: An RRule compliant with RFC 5545 that defines the recurrence rule for the Scheduled Task. For example "FREQ=DAILY;INTERVAL=1" to run the Scheduled Task every day. An empty string means, it does not repeat. Pass `None` to leave this unchanged.
:param timezone A timezone for the scheduled task, set to None to leave this as is.
:param starts_at: A date time string in ISO 8601 format that defines when the Scheduled Task should start. For example "2025-01-01T09:00:00Z". If not provided, the Scheduled Task will start immediately. Pass `None` to leave this unchanged.
:return:
"""
Expand All @@ -61,6 +65,7 @@ async def update_scheduled_task(id: int, prompt: None|str = None, recurrence_rul
'prompt': prompt,
'recurrence': recurrence_rule,
'startsAt': int(datetime.datetime.fromisoformat(starts_at.replace('Z', '+00:00')).timestamp()) if starts_at is not None else None,
'timezone': pytz.timezone(timezone).zone if timezone is not None else None
})

@tool
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 @@ -98,7 +98,7 @@ async def find_person_in_contacts(name: str) -> list[dict[str, typing.Any]]:
@safe_tool
async def find_details_of_current_user() -> dict[str, typing.Any]:
"""
Find the current user's personal information
Find the current user's personal information, such as name, location, timezone, language
:return: a dictionary with the person's personal information
"""

Expand Down
Loading