main
py 163 lines 6.33 KB
Raw
1 from helpers.api import ApiHandler, Input, Output, Request
2 from helpers.task_scheduler import (
3 TaskScheduler, ScheduledTask, AdHocTask, PlannedTask, TaskSchedule,
4 serialize_task, parse_task_schedule, parse_task_plan, TaskType
5 )
6 from helpers.projects import load_basic_project_data
7 from helpers.localization import Localization
8 from helpers.print_style import PrintStyle
9 import random
10
11
12 class SchedulerTaskCreate(ApiHandler):
13 async def process(self, input: Input, request: Request) -> Output:
14 """
15 Create a new task in the scheduler
16 """
17 printer = PrintStyle(italic=True, font_color="blue", padding=False)
18
19 # Get timezone from input (do not set if not provided, we then rely on poll() to set it)
20 if timezone := input.get("timezone", None):
21 Localization.get().set_timezone(timezone)
22
23 scheduler = TaskScheduler.get()
24 await scheduler.reload()
25
26 # Get common fields from input
27 name = input.get("name")
28 system_prompt = input.get("system_prompt", "")
29 prompt = input.get("prompt")
30 attachments = input.get("attachments", [])
31
32 requested_project_slug = input.get("project_name")
33 if isinstance(requested_project_slug, str):
34 requested_project_slug = requested_project_slug.strip() or None
35 else:
36 requested_project_slug = None
37
38 project_slug = requested_project_slug
39 project_color = None
40
41 if project_slug:
42 try:
43 metadata = load_basic_project_data(requested_project_slug)
44 project_color = metadata.get("color") or None
45 except Exception as exc:
46 printer.error(f"SchedulerTaskCreate: failed to load project '{project_slug}': {exc}")
47 return {"error": f"Saving project failed: {project_slug}"}
48
49 # Always dedicated context for scheduler tasks created by ui
50 task_context_id = None
51
52 # Check if schedule is provided (for ScheduledTask)
53 schedule = input.get("schedule", {})
54 token: str = input.get("token", "")
55
56 # Debug log the token value
57 printer.print(f"Token received from frontend: '{token}' (type: {type(token)}, length: {len(token) if token else 0})")
58
59 # Generate a random token if empty or not provided
60 if not token:
61 token = str(random.randint(1000000000000000000, 9999999999999999999))
62 printer.print(f"Generated new token: '{token}'")
63
64 plan = input.get("plan", {})
65
66 # Validate required fields
67 if not name or not prompt:
68 # return {"error": "Missing required fields: name, system_prompt, prompt"}
69 raise ValueError("Missing required fields: name, system_prompt, prompt")
70
71 task = None
72 if schedule:
73 # Create a scheduled task
74 # Handle different schedule formats (string or object)
75 if isinstance(schedule, str):
76 # Parse the string schedule
77 parts = schedule.split(' ')
78 task_schedule = TaskSchedule(
79 minute=parts[0] if len(parts) > 0 else "*",
80 hour=parts[1] if len(parts) > 1 else "*",
81 day=parts[2] if len(parts) > 2 else "*",
82 month=parts[3] if len(parts) > 3 else "*",
83 weekday=parts[4] if len(parts) > 4 else "*"
84 )
85 elif isinstance(schedule, dict):
86 # Use our standardized parsing function
87 try:
88 task_schedule = parse_task_schedule(schedule)
89 except ValueError as e:
90 raise ValueError(str(e))
91 else:
92 raise ValueError("Invalid schedule format. Must be string or object.")
93
94 task = ScheduledTask.create(
95 name=name,
96 system_prompt=system_prompt,
97 prompt=prompt,
98 schedule=task_schedule,
99 attachments=attachments,
100 context_id=task_context_id,
101 timezone=timezone,
102 project_name=project_slug,
103 project_color=project_color,
104 )
105 elif plan:
106 # Create a planned task
107 try:
108 # Use our standardized parsing function
109 task_plan = parse_task_plan(plan)
110 except ValueError as e:
111 return {"error": str(e)}
112
113 task = PlannedTask.create(
114 name=name,
115 system_prompt=system_prompt,
116 prompt=prompt,
117 plan=task_plan,
118 attachments=attachments,
119 context_id=task_context_id,
120 project_name=project_slug,
121 project_color=project_color,
122 )
123 else:
124 # Create an ad-hoc task
125 printer.print(f"Creating AdHocTask with token: '{token}'")
126 task = AdHocTask.create(
127 name=name,
128 system_prompt=system_prompt,
129 prompt=prompt,
130 token=token,
131 attachments=attachments,
132 context_id=task_context_id,
133 project_name=project_slug,
134 project_color=project_color,
135 )
136 # Verify token after creation
137 if isinstance(task, AdHocTask):
138 printer.print(f"AdHocTask created with token: '{task.token}'")
139
140 # Add the task to the scheduler
141 await scheduler.add_task(task)
142
143 # Verify the task was added correctly - retrieve by UUID to check persistence
144 saved_task = scheduler.get_task_by_uuid(task.uuid)
145 if saved_task:
146 if saved_task.type == TaskType.AD_HOC and isinstance(saved_task, AdHocTask):
147 printer.print(f"Task verified after save, token: '{saved_task.token}'")
148 else:
149 printer.print("Task verified after save, not an adhoc task")
150 else:
151 printer.print("WARNING: Task not found after save!")
152
153 # Return the created task using our standardized serialization function
154 task_dict = serialize_task(task)
155
156 # Debug log the serialized task
157 if task_dict and task_dict.get('type') == 'adhoc':
158 printer.print(f"Serialized adhoc task, token in response: '{task_dict.get('token')}'")
159
160 return {
161 "ok": True,
162 "task": task_dict
163 }