diff --git a/src/khoj/processor/conversation/prompts.py b/src/khoj/processor/conversation/prompts.py index 357f406e..77ac4214 100644 --- a/src/khoj/processor/conversation/prompts.py +++ b/src/khoj/processor/conversation/prompts.py @@ -1137,6 +1137,26 @@ Khoj: ) +automation_format_prompt = PromptTemplate.from_template( + """ +You are Khoj, a smart and creative researcher and writer with a knack for creating engaging content. +- You *CAN REMEMBER ALL NOTES and PERSONAL INFORMATION FOREVER* that the user ever shares with you. +- You *CAN* generate look-up real-time information from the internet, send notifications and answer questions based on the user's notes. + +Convert the AI response into a clear, structured markdown report with section headings to improve readability. +Your response will be sent in the body of an email to the user. +Do not add an email subject. Never add disclaimers in your final response. + +You are provided the following details for context. + +{username} +Original User Query: {original_query} +Executed Chat Request: {executed_query} +AI Response: {response} +Khoj: +""".strip() +) + # System messages to user # -- help_message = PromptTemplate.from_template( diff --git a/src/khoj/routers/helpers.py b/src/khoj/routers/helpers.py index 773afe25..6dcb1b4b 100644 --- a/src/khoj/routers/helpers.py +++ b/src/khoj/routers/helpers.py @@ -1634,6 +1634,25 @@ class CommonQueryParamsClass: CommonQueryParams = Annotated[CommonQueryParamsClass, Depends()] +def format_automation_response(scheduling_request: str, executed_query: str, ai_response: str, user: KhojUser) -> bool: + """ + Format the AI response to send in automation email to user. + """ + name = get_user_name(user) + if name: + username = prompts.user_name.format(name=name) + + automation_format_prompt = prompts.automation_format_prompt.format( + original_query=scheduling_request, + executed_query=executed_query, + response=ai_response, + username=username, + ) + + with timer("Chat actor: Format automation response", logger): + return send_message_to_model_wrapper_sync(automation_format_prompt, user=user) + + def should_notify(original_query: str, executed_query: str, ai_response: str, user: KhojUser) -> bool: """ Decide whether to notify the user of the AI response. @@ -1651,9 +1670,13 @@ def should_notify(original_query: str, executed_query: str, ai_response: str, us with timer("Chat actor: Decide to notify user of automation response", logger): try: # TODO Replace with async call so we don't have to maintain a sync version - response = send_message_to_model_wrapper_sync(to_notify_or_not, user=user, response_type="json_object") - should_notify_result = json.loads(response)["decision"] == "Yes" - logger.info(f'Decided to {"not " if not should_notify_result else ""}notify user of automation response.') + raw_response = send_message_to_model_wrapper_sync(to_notify_or_not, user=user, response_type="json_object") + response = json.loads(raw_response) + should_notify_result = response["decision"] == "Yes" + reason = response.get("reason", "unknown") + logger.info( + f'Decided to {"not " if not should_notify_result else ""}notify user of automation response because of reason: {reason}.' + ) return should_notify_result except Exception as e: logger.warning( @@ -1754,10 +1777,12 @@ def scheduled_chat( if should_notify( original_query=scheduling_request, executed_query=cleaned_query, ai_response=ai_response, user=user ): + formatted_response = format_automation_response(scheduling_request, cleaned_query, ai_response, user) + if is_resend_enabled(): - send_task_email(user.get_short_name(), user.email, cleaned_query, ai_response, subject, is_image) + send_task_email(user.get_short_name(), user.email, cleaned_query, formatted_response, subject, is_image) else: - return raw_response + return formatted_response async def create_automation(