diff --git a/ai/ai_config.json b/ai/ai_config.json index d71deb4..2c6a005 100644 --- a/ai/ai_config.json +++ b/ai/ai_config.json @@ -3,8 +3,8 @@ "max_tokens": 8192, "prompts": { "command_parser": { - "system": "You are a helpful AI assistant that parses user commands into structured JSON. Extract the user's intent and relevant parameters from natural language. Return ONLY valid JSON, no explanations.\n\nBe flexible with language - handle typos, slang, and casual phrasing. Consider conversation context when available.\n\n=== TIME CONVERSION RULES ===\nConvert all times to 24-hour format HH:MM in a JSON array:\n- \"4:20pm\", \"4:20 PM\" → [\"16:20\"]\n- \"9am\", \"9 AM\" → [\"09:00\"]\n- \"morning\" → [\"09:00\"]\n- \"evening\", \"night\" → [\"20:00\"]\n- \"noon\" → [\"12:00\"]\n- \"midnight\" → [\"00:00\"]\n- \"4:20\" (ambiguous) → set needs_clarification: \"Is that 4:20 AM or PM?\"\n- Multiple times: \"9am and 9pm\" → [\"09:00\", \"21:00\"]\n\n=== FREQUENCY MAPPING ===\nMap natural language to exact enum values:\n- \"every day\", \"daily\" → frequency: \"daily\"\n- \"twice a day\", \"twice daily\", \"2x daily\" → frequency: \"twice_daily\", times: [\"08:00\", \"20:00\"] (unless specified otherwise)\n- \"every tuesday\", \"tuesdays\" → frequency: \"specific_days\", days_of_week: [\"tue\"]\n- \"monday wednesday friday\", \"m/w/f\" → frequency: \"specific_days\", days_of_week: [\"mon\", \"wed\", \"fri\"]\n- \"every 3 days\", \"every three days\" → frequency: \"every_n_days\", interval_days: 3\n- \"as needed\", \"prn\" → frequency: \"as_needed\", times: []\n\nDay abbreviations: mon, tue, wed, thu, fri, sat, sun\n\n=== DOSAGE EXTRACTION ===\n- \"50 mcg\" → dosage: 50, unit: \"mcg\"\n- \"1 pill\", \"one pill\" → dosage: 1, unit: \"pill\"\n- \"5mg\" → dosage: 5, unit: \"mg\"\n- \"100 micrograms\" → dosage: 100, unit: \"mcg\"\n- No dosage mentioned → set needs_clarification\n\n=== VALIDATION RULES ===\nSet needs_clarification if:\n1. Dosage is missing for 'add' action\n2. Time is ambiguous (e.g., just \"4:20\" without AM/PM)\n3. Frequency is unclear (e.g., \"sometimes\", \"often\")\n4. Name cannot be determined\n\n=== INTERACTION TYPES ===\n- \"routine\": habits, routines, activities with steps\n- \"medication\": medications, drugs, supplements, vitamins\n\nAvailable actions:\n- routine: create, create_with_steps, list, start, complete, skip, cancel, pause, resume, steps, schedule, stats, history\n- medication: add, list, take, skip, today, refills, snooze, adherence\n\n=== STEP EXTRACTION FOR ROUTINES ===\nWhen user mentions creating a routine WITH steps:\n- \"create morning routine with brush teeth, shower, eat\"\n → action: \"create_with_steps\", name: \"morning routine\", steps: [\"brush teeth\", \"shower\", \"eat\"], needs_confirmation: true\n- \"add steps to X: A, B, C\" → action: \"add_steps\", routine_name: \"X\", steps: [\"A\", \"B\", \"C\"]", - "user_template": "Parse this command into structured JSON.\n\nCurrent conversation context:\n{history_context}\n\nUser message: \"{user_input}\"\n\nReturn JSON with these exact fields:\n{{\n \"interaction_type\": \"routine\" | \"medication\",\n \"action\": \"string\",\n \"name\": \"string\" (med/routine name),\n \"routine_name\": \"string\" (for step-related actions),\n \"description\": \"string\" (optional),\n \"steps\": [\"step1\", \"step2\"] (for routine creation),\n \"dosage\": number (for meds),\n \"unit\": \"string\" (mg, mcg, pill, etc),\n \"frequency\": \"daily\" | \"twice_daily\" | \"specific_days\" | \"every_n_days\" | \"as_needed\",\n \"times\": [\"HH:MM\"],\n \"days_of_week\": [\"mon\", \"tue\", ...],\n \"interval_days\": number (for every_n_days),\n \"needs_confirmation\": boolean (true for destructive/create actions),\n \"confirmation_prompt\": \"string\" (what to ask user),\n \"confidence\": number (0-1),\n \"needs_clarification\": \"string\" (if confidence < 0.8 or missing required fields)\n}}\n\n=== EXAMPLES ===\n\nMedication examples:\n1. User: \"take a giant dab of THC\"\n {{\"interaction_type\": \"medication\", \"action\": \"take\", \"name\": \"THC\", \"confidence\": 0.9}}\n\n2. User: \"add lsd 50 mcg daily at 9am\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"dosage\": 50, \"unit\": \"mcg\", \"frequency\": \"daily\", \"times\": [\"09:00\"], \"confidence\": 0.95}}\n\n3. User: \"add wellbutrin 150 mg twice daily\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"wellbutrin\", \"dosage\": 150, \"unit\": \"mg\", \"frequency\": \"twice_daily\", \"times\": [\"08:00\", \"20:00\"], \"confidence\": 0.95}}\n\n4. User: \"add vitamin d on tuesday and saturday at 8am\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"vitamin d\", \"dosage\": 1, \"unit\": \"pill\", \"frequency\": \"specific_days\", \"times\": [\"08:00\"], \"days_of_week\": [\"tue\", \"sat\"], \"confidence\": 0.95}}\n\n5. User: \"add lsd every tuesday at 4:20\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"needs_clarification\": \"Is that 4:20 AM or PM?\", \"confidence\": 0.7}}\n\n6. User: \"which meds do I have?\"\n {{\"interaction_type\": \"medication\", \"action\": \"list\", \"confidence\": 0.95}}\n\n7. User: \"what's my schedule today?\"\n {{\"interaction_type\": \"medication\", \"action\": \"today\", \"confidence\": 0.9}}\n\n8. User: \"any refills due?\"\n {{\"interaction_type\": \"medication\", \"action\": \"refills\", \"confidence\": 0.9}}\n\n9. User: \"snooze my reminder for 30 minutes\"\n {{\"interaction_type\": \"medication\", \"action\": \"snooze\", \"minutes\": 30, \"confidence\": 0.9}}\n\nRoutine examples:\n10. User: \"create a morning routine\"\n {{\"interaction_type\": \"routine\", \"action\": \"create\", \"name\": \"morning routine\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Create routine 'morning routine'?\", \"confidence\": 0.9}}\n\n11. User: \"create morning routine with brush teeth, shower, eat breakfast\"\n {{\"interaction_type\": \"routine\", \"action\": \"create_with_steps\", \"name\": \"morning routine\", \"steps\": [\"brush teeth\", \"shower\", \"eat breakfast\"], \"needs_confirmation\": true, \"confirmation_prompt\": \"Create 'morning routine' with 3 steps?\", \"confidence\": 0.95}}\n\n12. User: \"add steps to morning routine: meditate, journal\"\n {{\"interaction_type\": \"routine\", \"action\": \"add_steps\", \"routine_name\": \"morning routine\", \"steps\": [\"meditate\", \"journal\"], \"confidence\": 0.9}}\n\n13. User: \"what steps are in my morning routine?\"\n {{\"interaction_type\": \"routine\", \"action\": \"steps\", \"name\": \"morning routine\", \"confidence\": 0.9}}\n\n14. User: \"start morning routine\"\n {{\"interaction_type\": \"routine\", \"action\": \"start\", \"name\": \"morning routine\", \"confidence\": 0.9}}\n\n15. User: \"done\" (when in active session)\n {{\"interaction_type\": \"routine\", \"action\": \"complete\", \"confidence\": 0.9}}\n\n16. User: \"skip this step\"\n {{\"interaction_type\": \"routine\", \"action\": \"skip\", \"confidence\": 0.9}}\n\n17. User: \"schedule morning routine for monday wednesday friday at 7am\"\n {{\"interaction_type\": \"routine\", \"action\": \"schedule\", \"name\": \"morning routine\", \"days_of_week\": [\"mon\", \"wed\", \"fri\"], \"times\": [\"07:00\"], \"confidence\": 0.9}}\n\n18. User: \"show my routine stats\"\n {{\"interaction_type\": \"routine\", \"action\": \"stats\", \"confidence\": 0.9}}\n\n19. User: \"I want to create a habit called smoke dope\"\n {{\"interaction_type\": \"routine\", \"action\": \"create\", \"name\": \"smoke dope\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Create routine 'smoke dope'?\", \"confidence\": 0.9}}\n\n20. User: \"add lsd\" (missing dosage)\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"needs_clarification\": \"What's the dosage for lsd?\", \"confidence\": 0.6}}\n\nIf the user describes something but key info is missing, set needs_clarification explaining what's needed." + "system": "You are a helpful AI assistant that parses user commands into structured JSON. Extract the user's intent and relevant parameters from natural language. Return ONLY valid JSON, no explanations.\n\nBe flexible with language - handle typos, slang, and casual phrasing. Consider conversation context when available.\n\n=== TIME CONVERSION RULES ===\nConvert all times to 24-hour format HH:MM in a JSON array:\n- \"4:20pm\", \"4:20 PM\" → [\"16:20\"]\n- \"9am\", \"9 AM\" → [\"09:00\"]\n- \"morning\" → [\"09:00\"]\n- \"evening\", \"night\" → [\"20:00\"]\n- \"noon\" → [\"12:00\"]\n- \"midnight\" → [\"00:00\"]\n- \"4:20\" (ambiguous) → set needs_clarification: \"Is that 4:20 AM or PM?\"\n- Multiple times: \"9am and 9pm\" → [\"09:00\", \"21:00\"]\n\n=== FREQUENCY MAPPING ===\nMap natural language to exact enum values:\n- \"every day\", \"daily\" → frequency: \"daily\"\n- \"twice a day\", \"twice daily\", \"2x daily\" → frequency: \"twice_daily\", times: [\"08:00\", \"20:00\"] (unless specified otherwise)\n- \"every tuesday\", \"tuesdays\" → frequency: \"specific_days\", days_of_week: [\"tue\"]\n- \"monday wednesday friday\", \"m/w/f\" → frequency: \"specific_days\", days_of_week: [\"mon\", \"wed\", \"fri\"]\n- \"every 3 days\", \"every three days\" → frequency: \"every_n_days\", interval_days: 3\n- \"as needed\", \"prn\" → frequency: \"as_needed\", times: []\n\nDay abbreviations: mon, tue, wed, thu, fri, sat, sun\n\n=== DOSAGE EXTRACTION ===\n- \"50 mcg\" → dosage: 50, unit: \"mcg\"\n- \"1 pill\", \"one pill\" → dosage: 1, unit: \"pill\"\n- \"5mg\" → dosage: 5, unit: \"mg\"\n- \"100 micrograms\" → dosage: 100, unit: \"mcg\"\n- No dosage mentioned → set needs_clarification\n\n=== VALIDATION RULES ===\nSet needs_clarification if:\n1. Dosage is missing for 'add' action\n2. Time is ambiguous (e.g., just \"4:20\" without AM/PM)\n3. Frequency is unclear (e.g., \"sometimes\", \"often\")\n4. Name cannot be determined\n\n=== INTERACTION TYPES ===\n- \"routine\": habits, routines, activities with steps\n- \"medication\": medications, drugs, supplements, vitamins\n\nAvailable actions:\n- routine: create, create_with_steps, list, start, complete, skip, cancel, pause, resume, steps, schedule, stats, history, delete\n- medication: add, delete, list, take, skip, today, refills, snooze, adherence\n\n=== STEP EXTRACTION FOR ROUTINES ===\nWhen user mentions creating a routine WITH steps:\n- \"create morning routine with brush teeth, shower, eat\"\n → action: \"create_with_steps\", name: \"morning routine\", steps: [\"brush teeth\", \"shower\", \"eat\"], needs_confirmation: true\n- \"add steps to X: A, B, C\" → action: \"add_steps\", routine_name: \"X\", steps: [\"A\", \"B\", \"C\"]\n\n=== DELETE ACTIONS ===\nDelete actions are DESTRUCTIVE and should always require confirmation:\n- \"delete my lsd medication\" → action: \"delete\", name: \"lsd\", needs_confirmation: true\n- \"remove wellbutrin\" → action: \"delete\", name: \"wellbutrin\", needs_confirmation: true\n- \"get rid of vitamin d\" → action: \"delete\", name: \"vitamin d\", needs_confirmation: true", + "user_template": "Parse this command into structured JSON.\n\nCurrent conversation context:\n{history_context}\n\nUser message: \"{user_input}\"\n\nReturn JSON with these exact fields:\n{{\n \"interaction_type\": \"routine\" | \"medication\",\n \"action\": \"string\",\n \"name\": \"string\" (med/routine name),\n \"routine_name\": \"string\" (for step-related actions),\n \"description\": \"string\" (optional),\n \"steps\": [\"step1\", \"step2\"] (for routine creation),\n \"dosage\": number (for meds),\n \"unit\": \"string\" (mg, mcg, pill, etc),\n \"frequency\": \"daily\" | \"twice_daily\" | \"specific_days\" | \"every_n_days\" | \"as_needed\",\n \"times\": [\"HH:MM\"],\n \"days_of_week\": [\"mon\", \"tue\", ...],\n \"interval_days\": number (for every_n_days),\n \"needs_confirmation\": boolean (true for destructive/create actions),\n \"confirmation_prompt\": \"string\" (what to ask user),\n \"confidence\": number (0-1),\n \"needs_clarification\": \"string\" (if confidence < 0.8 or missing required fields)\n}}\n\n=== EXAMPLES ===\n\nMedication examples:\n1. User: \"take a giant dab of THC\"\n {{\"interaction_type\": \"medication\", \"action\": \"take\", \"name\": \"THC\", \"confidence\": 0.9}}\n\n2. User: \"add lsd 50 mcg daily at 9am\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"dosage\": 50, \"unit\": \"mcg\", \"frequency\": \"daily\", \"times\": [\"09:00\"], \"confidence\": 0.95}}\n\n3. User: \"add wellbutrin 150 mg twice daily\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"wellbutrin\", \"dosage\": 150, \"unit\": \"mg\", \"frequency\": \"twice_daily\", \"times\": [\"08:00\", \"20:00\"], \"confidence\": 0.95}}\n\n4. User: \"add vitamin d on tuesday and saturday at 8am\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"vitamin d\", \"dosage\": 1, \"unit\": \"pill\", \"frequency\": \"specific_days\", \"times\": [\"08:00\"], \"days_of_week\": [\"tue\", \"sat\"], \"confidence\": 0.95}}\n\n5. User: \"add lsd every tuesday at 4:20\"\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"needs_clarification\": \"Is that 4:20 AM or PM?\", \"confidence\": 0.7}}\n\n6. User: \"delete my lsd medication\"\n {{\"interaction_type\": \"medication\", \"action\": \"delete\", \"name\": \"lsd\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Are you sure you want to delete lsd?\", \"confidence\": 0.95}}\n\n7. User: \"remove wellbutrin\"\n {{\"interaction_type\": \"medication\", \"action\": \"delete\", \"name\": \"wellbutrin\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Are you sure you want to delete wellbutrin?\", \"confidence\": 0.95}}\n\n8. User: \"which meds do I have?\"\n {{\"interaction_type\": \"medication\", \"action\": \"list\", \"confidence\": 0.95}}\n\n9. User: \"what's my schedule today?\"\n {{\"interaction_type\": \"medication\", \"action\": \"today\", \"confidence\": 0.9}}\n\n10. User: \"any refills due?\"\n {{\"interaction_type\": \"medication\", \"action\": \"refills\", \"confidence\": 0.9}}\n\n11. User: \"snooze my reminder for 30 minutes\"\n {{\"interaction_type\": \"medication\", \"action\": \"snooze\", \"minutes\": 30, \"confidence\": 0.9}}\n\nRoutine examples:\n12. User: \"create a morning routine\"\n {{\"interaction_type\": \"routine\", \"action\": \"create\", \"name\": \"morning routine\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Create routine 'morning routine'?\", \"confidence\": 0.9}}\n\n13. User: \"create morning routine with brush teeth, shower, eat breakfast\"\n {{\"interaction_type\": \"routine\", \"action\": \"create_with_steps\", \"name\": \"morning routine\", \"steps\": [\"brush teeth\", \"shower\", \"eat breakfast\"], \"needs_confirmation\": true, \"confirmation_prompt\": \"Create 'morning routine' with 3 steps?\", \"confidence\": 0.95}}\n\n14. User: \"add steps to morning routine: meditate, journal\"\n {{\"interaction_type\": \"routine\", \"action\": \"add_steps\", \"routine_name\": \"morning routine\", \"steps\": [\"meditate\", \"journal\"], \"confidence\": 0.9}}\n\n15. User: \"what steps are in my morning routine?\"\n {{\"interaction_type\": \"routine\", \"action\": \"steps\", \"name\": \"morning routine\", \"confidence\": 0.9}}\n\n16. User: \"start morning routine\"\n {{\"interaction_type\": \"routine\", \"action\": \"start\", \"name\": \"morning routine\", \"confidence\": 0.9}}\n\n17. User: \"done\" (when in active session)\n {{\"interaction_type\": \"routine\", \"action\": \"complete\", \"confidence\": 0.9}}\n\n18. User: \"skip this step\"\n {{\"interaction_type\": \"routine\", \"action\": \"skip\", \"confidence\": 0.9}}\n\n19. User: \"schedule morning routine for monday wednesday friday at 7am\"\n {{\"interaction_type\": \"routine\", \"action\": \"schedule\", \"name\": \"morning routine\", \"days_of_week\": [\"mon\", \"wed\", \"fri\"], \"times\": [\"07:00\"], \"confidence\": 0.9}}\n\n20. User: \"show my routine stats\"\n {{\"interaction_type\": \"routine\", \"action\": \"stats\", \"confidence\": 0.9}}\n\n21. User: \"I want to create a habit called smoke dope\"\n {{\"interaction_type\": \"routine\", \"action\": \"create\", \"name\": \"smoke dope\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Create routine 'smoke dope'?\", \"confidence\": 0.9}}\n\n22. User: \"delete morning routine\"\n {{\"interaction_type\": \"routine\", \"action\": \"delete\", \"name\": \"morning routine\", \"needs_confirmation\": true, \"confirmation_prompt\": \"Are you sure you want to delete morning routine?\", \"confidence\": 0.95}}\n\n23. User: \"add lsd\" (missing dosage)\n {{\"interaction_type\": \"medication\", \"action\": \"add\", \"name\": \"lsd\", \"needs_clarification\": \"What's the dosage for lsd?\", \"confidence\": 0.6}}\n\nIf unclear, set needs_clarification explaining what's needed." } }, "validation": { diff --git a/bot/commands/medications.py b/bot/commands/medications.py index 6daf392..3386a42 100644 --- a/bot/commands/medications.py +++ b/bot/commands/medications.py @@ -225,8 +225,49 @@ async def handle_medication(message, session, parsed): else: await message.channel.send(f"Error: {resp.get('error', 'Failed to fetch adherence')}") + elif action == "delete": + med_id = parsed.get("medication_id") + name = parsed.get("name") + needs_confirmation = parsed.get("needs_confirmation", True) + + med_id, name, found = await _find_medication_by_name(message, token, med_id, name) + if not found: + return + + if not med_id: + await message.channel.send("Which medication should I delete?") + return + + # Handle confirmation + if needs_confirmation: + if "pending_confirmations" not in session: + session["pending_confirmations"] = {} + + confirmation_id = f"med_delete_{name}" + session["pending_confirmations"][confirmation_id] = { + "action": "delete", + "interaction_type": "medication", + "medication_id": med_id, + "name": name, + "needs_confirmation": False # Skip confirmation next time + } + + await message.channel.send( + f"⚠️ Are you sure you want to delete **{name}**?\n\n" + f"This will also delete all logs for this medication.\n\n" + f"Reply **yes** to confirm deletion, or **no** to cancel." + ) + return + + # Actually delete + resp, status = api_request("delete", f"/api/medications/{med_id}", token) + if status == 200: + await message.channel.send(f"🗑️ Deleted **{name}** and all its logs.") + else: + await message.channel.send(f"Error: {resp.get('error', 'Failed to delete medication')}") + else: - await message.channel.send(f"Unknown action: {action}. Try: list, add, take, skip, today, refills, snooze, or adherence.") + await message.channel.send(f"Unknown action: {action}. Try: list, add, delete, take, skip, today, refills, snooze, or adherence.") async def _add_medication(message, token, name, dosage, unit, frequency, times, days_of_week, interval_days): diff --git a/bot/commands/routines.py b/bot/commands/routines.py index 658f605..161c113 100644 --- a/bot/commands/routines.py +++ b/bot/commands/routines.py @@ -458,8 +458,49 @@ async def handle_routine(message, session, parsed): else: await message.channel.send(f"Error: {resp.get('error', 'Failed to add tag')}") + elif action == "delete": + routine_id = parsed.get("routine_id") + name = parsed.get("name") + needs_confirmation = parsed.get("needs_confirmation", True) + + routine_id, name, found = await _find_routine_by_name(message, token, routine_id, name) + if not found: + return + + if not routine_id: + await message.channel.send("Which routine should I delete?") + return + + # Handle confirmation + if needs_confirmation: + if "pending_confirmations" not in session: + session["pending_confirmations"] = {} + + confirmation_id = f"routine_delete_{name}" + session["pending_confirmations"][confirmation_id] = { + "action": "delete", + "interaction_type": "routine", + "routine_id": routine_id, + "name": name, + "needs_confirmation": False # Skip confirmation next time + } + + await message.channel.send( + f"⚠️ Are you sure you want to delete **{name}**?\n\n" + f"This will also delete all steps and history for this routine.\n\n" + f"Reply **yes** to confirm deletion, or **no** to cancel." + ) + return + + # Actually delete + resp, status = api_request("delete", f"/api/routines/{routine_id}", token) + if status == 200: + await message.channel.send(f"🗑️ Deleted **{name}** and all its data.") + else: + await message.channel.send(f"Error: {resp.get('error', 'Failed to delete routine')}") + else: - await message.channel.send(f"Unknown action: {action}. Try: list, create, start, complete, skip, cancel, history, pause, resume, abort, note, stats, streak, templates, clone, or tag.") + await message.channel.send(f"Unknown action: {action}. Try: list, create, delete, start, complete, skip, cancel, history, pause, resume, abort, note, stats, streak, templates, clone, or tag.") async def _create_routine(message, token, name, description):