|
25 | 25 | send_email_reply, |
26 | 26 | ) |
27 | 27 | from mxgo.models import TaskStatus |
| 28 | +from mxgo.prompts.template_prompts import NEWSLETTER_TEMPLATE |
28 | 29 | from mxgo.reply_generation import generate_replies |
29 | 30 | from mxgo.scheduling.scheduled_task_executor import execute_scheduled_task |
30 | 31 | from mxgo.scheduling.scheduler import Scheduler, is_one_time_task |
@@ -880,17 +881,34 @@ async def generate_email_replies( |
880 | 881 |
|
881 | 882 | # Helper functions for create_newsletter |
882 | 883 | def _build_newsletter_instructions(request: CreateNewsletterRequest) -> str: |
883 | | - """Builds the full instruction string from the request.""" |
884 | | - full_instructions = [f"PROMPT: {request.prompt}"] |
| 884 | + """Builds the full instruction string from the request using the NEWSLETTER template.""" |
| 885 | + user_instructions = [] |
885 | 886 | if request.estimated_read_time: |
886 | | - full_instructions.append(f"ESTIMATED READ TIME: {request.estimated_read_time} minutes") |
| 887 | + user_instructions.append( |
| 888 | + f"- **Target Read Time**: The newsletter should be concise enough to be read in approximately {request.estimated_read_time} minutes." |
| 889 | + ) |
887 | 890 | if request.sources: |
888 | | - full_instructions.append(f"SOURCES: {', '.join(request.sources)}") |
| 891 | + user_instructions.append( |
| 892 | + f"- **Prioritize Sources**: When researching, give priority to information from the following sources: {', '.join(request.sources)}." |
| 893 | + ) |
889 | 894 | if request.geographic_locations: |
890 | | - full_instructions.append(f"GEOGRAPHIC FOCUS: {', '.join(request.geographic_locations)}") |
| 895 | + user_instructions.append( |
| 896 | + f"- **Geographic Focus**: The content should be primarily relevant to the following locations: {', '.join(request.geographic_locations)}." |
| 897 | + ) |
891 | 898 | if request.formatting_instructions: |
892 | | - full_instructions.append(f"FORMATTING INSTRUCTIONS: {request.formatting_instructions}") |
893 | | - return "\n\n".join(full_instructions) |
| 899 | + user_instructions.append( |
| 900 | + f"- **Formatting Rules**: Strictly follow these formatting instructions: {request.formatting_instructions}." |
| 901 | + ) |
| 902 | + |
| 903 | + if user_instructions: |
| 904 | + user_instructions_section = "\n".join(user_instructions) |
| 905 | + else: |
| 906 | + user_instructions_section = ( |
| 907 | + "No specific user instructions were provided. Use your best judgment to create a high-quality newsletter." |
| 908 | + ) |
| 909 | + |
| 910 | + # This becomes the detailed, distilled instructions for the agent. |
| 911 | + return NEWSLETTER_TEMPLATE.format(prompt=request.prompt, user_instructions_section=user_instructions_section) |
894 | 912 |
|
895 | 913 |
|
896 | 914 | async def _validate_newsletter_limits(user_email: str, cron_expressions: list[str]): |
@@ -953,7 +971,16 @@ def _create_and_schedule_task(user_email: str, cron_expr: str, distilled_instruc |
953 | 971 | ) |
954 | 972 |
|
955 | 973 | scheduler = Scheduler() |
956 | | - scheduler.add_job(job_id=scheduler_job_id, cron_expression=cron_expr, func=execute_scheduled_task, args=[task_id]) |
| 974 | + try: |
| 975 | + scheduler.add_job( |
| 976 | + job_id=scheduler_job_id, cron_expression=cron_expr, func=execute_scheduled_task, args=[task_id] |
| 977 | + ) |
| 978 | + except Exception as e: |
| 979 | + logger.error(f"Failed to schedule task {task_id}: {e}") |
| 980 | + |
| 981 | + with db_connection.get_session() as session: |
| 982 | + crud.delete_task(session, task_id) |
| 983 | + raise |
957 | 984 |
|
958 | 985 | with db_connection.get_session() as session: |
959 | 986 | crud.update_task_status(session, task_id, TaskStatus.ACTIVE) |
@@ -983,7 +1010,7 @@ async def _handle_post_creation_action( |
983 | 1010 | parent_message_id=f"<newsletter-parent-{first_task_id}@mxgo.ai>", |
984 | 1011 | ) |
985 | 1012 | process_email_task.send( |
986 | | - sample_email_request.model_dump(), |
| 1013 | + sample_email_request.model_dump(by_alias=True), |
987 | 1014 | email_attachments_dir="", |
988 | 1015 | attachment_info=[], |
989 | 1016 | scheduled_task_id=first_task_id, |
@@ -1018,17 +1045,14 @@ async def create_newsletter( |
1018 | 1045 | f"Duplicate request_id {request.request_id} detected for {user_email}, returning existing tasks from Redis" |
1019 | 1046 | ) |
1020 | 1047 | existing_task_ids = json.loads(existing_task_ids_json) |
1021 | | - return Response( |
1022 | | - content=json.dumps( |
1023 | | - { |
1024 | | - "message": "This request has already been processed.", |
1025 | | - "status": "duplicate", |
1026 | | - "request_id": request.request_id, |
1027 | | - "scheduled_task_ids": existing_task_ids, |
1028 | | - } |
1029 | | - ), |
| 1048 | + raise HTTPException( |
1030 | 1049 | status_code=status.HTTP_409_CONFLICT, |
1031 | | - media_type="application/json", |
| 1050 | + detail={ |
| 1051 | + "message": "This request has already been processed.", |
| 1052 | + "status": "duplicate", |
| 1053 | + "request_id": request.request_id, |
| 1054 | + "scheduled_task_ids": existing_task_ids, |
| 1055 | + }, |
1032 | 1056 | ) |
1033 | 1057 |
|
1034 | 1058 | distilled_instructions = _build_newsletter_instructions(request) |
@@ -1064,7 +1088,10 @@ async def create_newsletter( |
1064 | 1088 | except Exception as scheduler_e: |
1065 | 1089 | logger.error(f"Failed to remove scheduler job for task {tid}: {scheduler_e}") |
1066 | 1090 |
|
1067 | | - raise HTTPException(status_code=500, detail="Failed to schedule one or more newsletter tasks.") from e |
| 1091 | + raise HTTPException( |
| 1092 | + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
| 1093 | + detail="Failed to schedule one or more newsletter tasks.", |
| 1094 | + ) from e |
1068 | 1095 |
|
1069 | 1096 | sample_email_sent = False |
1070 | 1097 | if created_task_ids: |
|
0 commit comments