Spaces:
Runtime error
Runtime error
Update core/ai_engine.py
Browse files- core/ai_engine.py +28 -14
core/ai_engine.py
CHANGED
|
@@ -54,6 +54,8 @@ TASK_CAPTURE_PROMPT = """You are a task classification assistant for a productiv
|
|
| 54 |
|
| 55 |
Take the user's raw task description and return a structured JSON object.
|
| 56 |
|
|
|
|
|
|
|
| 57 |
Dimensions:
|
| 58 |
1. title (string): Clean, action-oriented task title.
|
| 59 |
2. life_area (string): ONE of: Work, Health, Learning, Finance, Personal, Family, Other
|
|
@@ -61,9 +63,13 @@ Dimensions:
|
|
| 61 |
4. importance (string): ONE of: Move the Needle | Important | Not Important
|
| 62 |
5. state_of_mind (string): ONE of: Flow | Easy | Quick | Personal
|
| 63 |
6. time_estimate (integer): Realistic minutes to complete.
|
| 64 |
-
7.
|
|
|
|
|
|
|
|
|
|
| 65 |
|
| 66 |
-
RETURN: Valid JSON only. No markdown, no prose. All
|
|
|
|
| 67 |
|
| 68 |
|
| 69 |
def parse_task_with_groq(raw_text: str, user_context: dict = None,
|
|
@@ -77,10 +83,12 @@ def parse_task_with_groq(raw_text: str, user_context: dict = None,
|
|
| 77 |
if life_areas:
|
| 78 |
context_hint += f"\nUser's life areas: {', '.join(life_areas)}"
|
| 79 |
|
|
|
|
|
|
|
| 80 |
response = _groq().chat.completions.create(
|
| 81 |
model=GROQ_MODEL,
|
| 82 |
messages=[
|
| 83 |
-
{"role": "system", "content":
|
| 84 |
{"role": "user", "content": f"Parse this task: {raw_text}"}
|
| 85 |
],
|
| 86 |
max_tokens=512,
|
|
@@ -93,6 +101,7 @@ def parse_task_with_groq(raw_text: str, user_context: dict = None,
|
|
| 93 |
"title": raw_text,
|
| 94 |
"life_area": None, "urgency": None, "importance": None,
|
| 95 |
"state_of_mind": None, "time_estimate": None,
|
|
|
|
| 96 |
"clarifications_needed": ["Could you give more details? Which area, how urgent, how long?"]
|
| 97 |
}
|
| 98 |
return result
|
|
@@ -102,8 +111,8 @@ def parse_task_with_groq(raw_text: str, user_context: dict = None,
|
|
| 102 |
|
| 103 |
SMART_SCHEDULER_PROMPT = """You are an intelligent task scheduler for Second Brain.
|
| 104 |
|
| 105 |
-
You assign UNSCHEDULED TASKS to specific future dates, like a smart personal assistant
|
| 106 |
-
user's rhythms, goals, energy patterns, and
|
| 107 |
|
| 108 |
REASONING PROCESS:
|
| 109 |
1. Read the user request carefully — honour it above all else
|
|
@@ -114,12 +123,14 @@ REASONING PROCESS:
|
|
| 114 |
2. Never assign to a date/time in the past (current datetime is given)
|
| 115 |
3. If current time is past 18:00, treat today as unavailable unless user explicitly asks
|
| 116 |
4. Prioritise by: deadline proximity > urgency > importance > goal alignment
|
| 117 |
-
5. Match tasks to
|
| 118 |
-
- Flow = peak
|
| 119 |
-
-
|
| 120 |
-
-
|
| 121 |
-
|
| 122 |
-
|
|
|
|
|
|
|
| 123 |
|
| 124 |
RETURN FORMAT (JSON only, no markdown):
|
| 125 |
{
|
|
@@ -128,7 +139,9 @@ RETURN FORMAT (JSON only, no markdown):
|
|
| 128 |
"task_id": 123,
|
| 129 |
"title": "Task title",
|
| 130 |
"assigned_date": "YYYY-MM-DD",
|
| 131 |
-
"
|
|
|
|
|
|
|
| 132 |
}
|
| 133 |
],
|
| 134 |
"skipped": [
|
|
@@ -138,10 +151,11 @@ RETURN FORMAT (JSON only, no markdown):
|
|
| 138 |
"reason": "why not assigned"
|
| 139 |
}
|
| 140 |
],
|
| 141 |
-
"summary": "2-3 sentence plain-English explanation of what was scheduled and why"
|
|
|
|
| 142 |
}
|
| 143 |
|
| 144 |
-
NEVER assign to a past date. NEVER ignore
|
| 145 |
|
| 146 |
|
| 147 |
def smart_schedule_tasks(
|
|
|
|
| 54 |
|
| 55 |
Take the user's raw task description and return a structured JSON object.
|
| 56 |
|
| 57 |
+
TODAY'S DATE: {today}
|
| 58 |
+
|
| 59 |
Dimensions:
|
| 60 |
1. title (string): Clean, action-oriented task title.
|
| 61 |
2. life_area (string): ONE of: Work, Health, Learning, Finance, Personal, Family, Other
|
|
|
|
| 63 |
4. importance (string): ONE of: Move the Needle | Important | Not Important
|
| 64 |
5. state_of_mind (string): ONE of: Flow | Easy | Quick | Personal
|
| 65 |
6. time_estimate (integer): Realistic minutes to complete.
|
| 66 |
+
7. deadline_date (string | null): If the user mentions ANY deadline, due date, or "by X" — extract as YYYY-MM-DD.
|
| 67 |
+
Examples: "by Friday" -> next Friday's date, "due March 1" -> "2026-03-01", "end of month" -> last day of current month.
|
| 68 |
+
If no deadline mentioned, return null.
|
| 69 |
+
8. clarifications_needed (array): Short specific questions if uncertain about any dimension. Return [] if confident.
|
| 70 |
|
| 71 |
+
RETURN: Valid JSON only. No markdown, no prose. All 8 fields always present.
|
| 72 |
+
CRITICAL: If user says "by [date]", "due [date]", "before [date]", "deadline [date]" — ALWAYS populate deadline_date."""
|
| 73 |
|
| 74 |
|
| 75 |
def parse_task_with_groq(raw_text: str, user_context: dict = None,
|
|
|
|
| 83 |
if life_areas:
|
| 84 |
context_hint += f"\nUser's life areas: {', '.join(life_areas)}"
|
| 85 |
|
| 86 |
+
today_str = date.today().isoformat()
|
| 87 |
+
system_prompt = TASK_CAPTURE_PROMPT.replace("{today}", today_str) + context_hint
|
| 88 |
response = _groq().chat.completions.create(
|
| 89 |
model=GROQ_MODEL,
|
| 90 |
messages=[
|
| 91 |
+
{"role": "system", "content": system_prompt},
|
| 92 |
{"role": "user", "content": f"Parse this task: {raw_text}"}
|
| 93 |
],
|
| 94 |
max_tokens=512,
|
|
|
|
| 101 |
"title": raw_text,
|
| 102 |
"life_area": None, "urgency": None, "importance": None,
|
| 103 |
"state_of_mind": None, "time_estimate": None,
|
| 104 |
+
"deadline_date": None,
|
| 105 |
"clarifications_needed": ["Could you give more details? Which area, how urgent, how long?"]
|
| 106 |
}
|
| 107 |
return result
|
|
|
|
| 111 |
|
| 112 |
SMART_SCHEDULER_PROMPT = """You are an intelligent task scheduler for Second Brain.
|
| 113 |
|
| 114 |
+
You assign UNSCHEDULED TASKS to specific future dates AND time blocks, like a smart personal assistant
|
| 115 |
+
who understands the user's rhythms, goals, energy patterns, and current time.
|
| 116 |
|
| 117 |
REASONING PROCESS:
|
| 118 |
1. Read the user request carefully — honour it above all else
|
|
|
|
| 123 |
2. Never assign to a date/time in the past (current datetime is given)
|
| 124 |
3. If current time is past 18:00, treat today as unavailable unless user explicitly asks
|
| 125 |
4. Prioritise by: deadline proximity > urgency > importance > goal alignment
|
| 126 |
+
5. Match tasks to time blocks by state_of_mind:
|
| 127 |
+
- Flow = peak focus window (morning if peak=Morning), 60-90 min blocks
|
| 128 |
+
- Easy = mid-morning or early afternoon, 20-45 min
|
| 129 |
+
- Quick = any gap, 10-20 min
|
| 130 |
+
- Personal = end of day or lunch, flexible
|
| 131 |
+
6. Respect wake/sleep times. Add 10min breaks between tasks. Don't exceed max_flow_block.
|
| 132 |
+
7. Spread load sensibly — don't overstack one day
|
| 133 |
+
8. Tasks with deadlines must land BEFORE that deadline
|
| 134 |
|
| 135 |
RETURN FORMAT (JSON only, no markdown):
|
| 136 |
{
|
|
|
|
| 139 |
"task_id": 123,
|
| 140 |
"title": "Task title",
|
| 141 |
"assigned_date": "YYYY-MM-DD",
|
| 142 |
+
"start_time": "09:00",
|
| 143 |
+
"end_time": "10:30",
|
| 144 |
+
"reasoning": "1 sentence why this slot"
|
| 145 |
}
|
| 146 |
],
|
| 147 |
"skipped": [
|
|
|
|
| 151 |
"reason": "why not assigned"
|
| 152 |
}
|
| 153 |
],
|
| 154 |
+
"summary": "2-3 sentence plain-English explanation of what was scheduled and why",
|
| 155 |
+
"warnings": ["any overload or conflict warnings"]
|
| 156 |
}
|
| 157 |
|
| 158 |
+
NEVER assign to a past date/time. NEVER ignore explicit user scheduling instructions."""
|
| 159 |
|
| 160 |
|
| 161 |
def smart_schedule_tasks(
|