eraz3r commited on
Commit
6351a26
·
verified ·
1 Parent(s): 15f33db

Update core/ai_engine.py

Browse files
Files changed (1) hide show
  1. 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. clarifications_needed (array): Short specific questions if uncertain about any dimension. Return [] if confident.
 
 
 
65
 
66
- RETURN: Valid JSON only. No markdown, no prose. All 7 fields always present."""
 
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": TASK_CAPTURE_PROMPT + context_hint},
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 who understands the
106
- user's rhythms, goals, energy patterns, and the current time.
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 days by state_of_mind:
118
- - Flow = peak days (Mon-Thu mornings if peak=Morning)
119
- - Quick/Easy = any day, fill gaps
120
- - Habit = today or tomorrow
121
- 6. Spread load don't stack everything on one day
122
- 7. Tasks with deadlines must land BEFORE that deadline
 
 
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
- "reasoning": "1 sentence why this date"
 
 
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 an explicit user instruction about when to schedule."""
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(