1616from datetime import datetime , timedelta
1717from typing import Annotated
1818
19-
2019import tzlocal
20+ from apscheduler .jobstores .sqlalchemy import SQLAlchemyJobStore
2121from apscheduler .schedulers .background import BackgroundScheduler
22- from apecheduler .jobstores .sqlalchemy import SQLAlchemyJobStore
2322from apscheduler .triggers .cron import CronTrigger
2423from apscheduler .triggers .cron .fields import BaseField
2524from fastapi import Depends , FastAPI , Response
3736# os.environ["NEXTCLOUD_URL"] = "http://nextcloud.local"
3837# os.environ["APP_PERSISTENT_STORAGE"] = "/tmp/"
3938
39+ # isort: off
4040# Imported here to register environment variables before importing store (only for local dev purposes)
4141import store
4242from store import database_path
4343
44- sqlite_url = f"sqlite:///{ database_path } "
45-
46-
44+ SQLITE_URI = f"sqlite:///{ database_path } "
4745
4846
4947class LLMException (Exception ):
@@ -59,10 +57,11 @@ class LLMException(Exception):
5957logger .setLevel (logging .DEBUG )
6058setup_nextcloud_logging (os .environ ["APP_ID" ], logging .WARNING )
6159
60+
6261# The same stuff as for usual External Applications
6362@asynccontextmanager
6463async def lifespan (app : FastAPI ):
65- set_handlers (app , enabled_handler )
64+ set_handlers (app , enabled_handler ) # pyright: ignore[reportArgumentType]
6665 yield
6766
6867
@@ -92,7 +91,7 @@ async def lifespan(app: FastAPI):
9291
9392Now, please provide an insighful summary of the provided chat log and use human-readable time references for time related information.
9493Use bullet points to list the most important facts and keep the summary concise and readable in roughly 30 seconds.
95- """ # noqa: E501
94+ """ # noqa: E501
9695
9796PROMPT_WINDOW = 16_000 - 4_000
9897"""Most models (proprietory and local) have an effective context length of 16000 tokens. We leave 4000 tokens for the
@@ -104,10 +103,7 @@ async def lifespan(app: FastAPI):
104103MAX_CHARACTERS = MAX_WORDS * 5
105104
106105
107-
108- jobstores = {
109- 'default' :SQLAlchemyJobStore (url = sqlite_url )
110- }
106+ jobstores = {"default" : SQLAlchemyJobStore (url = SQLITE_URI )}
111107
112108scheduler = BackgroundScheduler (jobstores = jobstores )
113109scheduler .start ()
@@ -223,17 +219,17 @@ def sched_process_request(message: talk_bot.TalkBotMessage, job_hash: str):
223219
224220def get_ctx_limited_messages (chat_messages : list [store .ChatMessages ]) -> tuple [str , str | None ]:
225221 """Get the last messages that fit into the context window of the model.
226- The second return is the cut-off datetime of the messages.
227- """
228222
223+ The second return is the cut-off datetime of the messages.
224+ """
229225 msgs = ""
230226 length = 0
231227 cutoff = None
232228
233229 for i in range (len (chat_messages ) - 1 , - 1 , - 1 ):
234230 msg = format_message (chat_messages [i ])
235231 if (length := length + len (msg )) > MAX_CHARACTERS :
236- cutoff = str (chat_messages [max (0 , i - 1 )].timestamp )
232+ cutoff = str (chat_messages [max (0 , i - 1 )].timestamp )
237233 break
238234
239235 msgs = msg + "\n " + msgs
@@ -258,17 +254,18 @@ def last_x_duration_process(message: talk_bot.TalkBotMessage, hduration: str = "
258254 )
259255 return
260256
261- duration = timedelta (seconds = timelength_res .to_seconds (max_precision = 0 ))
257+ duration = timedelta (seconds = timelength_res .to_milliseconds (max_precision = 0 ) * 0.001 )
262258 current_time = datetime .now ()
263259 start_time = current_time - duration
264260 start_time_str = start_time .strftime ("%Y-%m-%d %H:%M:%S" )
265261
266262 try :
267263 # Get the chat messages from the database
268- chat_messages = store .ChatMessages \
269- .select () \
270- .where (store .ChatMessages .room_id == message .conversation_token ) \
271- .where (store .ChatMessages .timestamp >= start_time_str )
264+ chat_messages = (
265+ store .ChatMessages .select ()
266+ .where (store .ChatMessages .room_id == message .conversation_token )
267+ .where (store .ChatMessages .timestamp >= start_time_str ) # pyright: ignore[reportOperatorIssue]
268+ )
272269
273270 if chat_messages .count () == 0 :
274271 BOT .send_message (f"```There was no conversation since i joined '{ message .conversation_name } '```" , message )
@@ -286,7 +283,9 @@ def last_x_duration_process(message: talk_bot.TalkBotMessage, hduration: str = "
286283 f" (All times are in { tz } timezone)*\n "
287284 )
288285 if cutoff :
289- ai_info += f"\n \n *Note: Messages before \" { cutoff } \" were not included in the summary due to the length limit.*"
286+ ai_info += (
287+ f'\n \n *Note: Messages before "{ cutoff } " were not included in the summary due to the length limit.*'
288+ )
290289 BOT .send_message (f"""**Summary:**\n { summary } \n \n { ai_info } """ , message )
291290 except LLMException :
292291 error_handler ("Could not get a summary from any large language model" , message )
@@ -297,7 +296,8 @@ def is_numbers_and_colon(s: str):
297296
298297
299298def help_message (message , text ):
300- BOT .send_message (f"""
299+ BOT .send_message (
300+ f"""
301301**{ os .environ ["APP_DISPLAY_NAME" ]} **:
302302*{ text } *
303303
@@ -321,7 +321,7 @@ def help_message(message, text):
321321Prints a help message:
322322 @summary help
323323```
324- """ , # noqa: E501
324+ """ , # noqa: E501
325325 message ,
326326 )
327327
@@ -418,7 +418,7 @@ def handle_command(message: talk_bot.TalkBotMessage):
418418 message ,
419419 "Invalid time string provided, please use '30m' for 30 minutes, '3h40m' for 3 hours and 40 minutes,"
420420 " '1d' for 1 day" ,
421- ) # noqa: E501
421+ ) # noqa: E501
422422 return
423423
424424 #########
@@ -454,7 +454,7 @@ def handle_command(message: talk_bot.TalkBotMessage):
454454 # Parameters for the new job
455455 new_job_hour = int (hour )
456456 new_job_minute = int (minute )
457- new_job_hash = f"{ conversation_token } _{ hashlib .md5 (f'{ conversation_token } _{ conversation_name } _{ new_job_hour } _{ new_job_minute } ' .encode ()).hexdigest ()} " # noqa: E501, S324
457+ new_job_hash = f"{ conversation_token } _{ hashlib .md5 (f'{ conversation_token } _{ conversation_name } _{ new_job_hour } _{ new_job_minute } ' .encode ()).hexdigest ()} " # noqa: E501, S324
458458
459459 # Check if a similar job already exists
460460 job_exists = False
@@ -472,7 +472,7 @@ def handle_command(message: talk_bot.TalkBotMessage):
472472 job_minute = trigger .fields [trigger .FIELD_NAMES .index ("minute" )]
473473 job_day_of_week = trigger .fields [trigger .FIELD_NAMES .index ("day_of_week" )]
474474
475- old_job_hash = f"{ old_conversation_token } _{ hashlib .md5 (f'{ old_conversation_token } _{ conversation_name } _{ job_hour } _{ job_minute } ' .encode ()).hexdigest ()} " # noqa: E501, S324
475+ old_job_hash = f"{ old_conversation_token } _{ hashlib .md5 (f'{ old_conversation_token } _{ conversation_name } _{ job_hour } _{ job_minute } ' .encode ()).hexdigest ()} " # noqa: E501, S324
476476
477477 if isinstance (job_hour , BaseField ):
478478 job_hour = job_hour .expressions [0 ]
@@ -500,8 +500,8 @@ def handle_command(message: talk_bot.TalkBotMessage):
500500 return
501501
502502 BOT .send_message (
503- f"```Skip - A { os .environ ['APP_DISPLAY_NAME' ]} job already exists at { job_hour } :{ job_minute } :00 for "
504- f" '{ conversation_name } '```" ,
503+ f"```Skip - A { os .environ ['APP_DISPLAY_NAME' ]} job already exists at { job_hour } :{ job_minute } :00"
504+ f" for '{ conversation_name } '```" ,
505505 message ,
506506 )
507507 return
@@ -525,8 +525,8 @@ def handle_command(message: talk_bot.TalkBotMessage):
525525 if minute <= 9 :
526526 minute = f"0{ minute } "
527527 BOT .send_message (
528- f"```New: Added a daily { os .environ ['APP_DISPLAY_NAME' ]} task at { hour } :{ minute } :00 for ' { conversation_name } ' with the "
529- f" id: { job_hash } ```" ,
528+ f"```New: Added a daily { os .environ ['APP_DISPLAY_NAME' ]} task at { hour } :{ minute } :00"
529+ f" for ' { conversation_name } ' with the id: { job_hash } ```" ,
530530 message ,
531531 )
532532 except Exception :
@@ -570,8 +570,7 @@ def handle_command(message: talk_bot.TalkBotMessage):
570570
571571 if not job_id_to_delete :
572572 BOT .send_message (
573- "```No Job ID to delete given - use '@summary list' to get a list of scheduled"
574- " job ids```" ,
573+ "```No Job ID to delete given - use '@summary list' to get a list of scheduled" " job ids```" ,
575574 message ,
576575 )
577576 return
0 commit comments