import anthropic import os import json from typing import List, Dict, Union, Any from dotenv import load_dotenv load_dotenv() # Load environment variables from .env file # Check for required environment variables if not os.getenv("ANTHROPIC_API_KEY"): raise ValueError("ANTHROPIC_API_KEY environment variable is not set") client = anthropic.Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY")) def llm_parse_tasks(user_input: str) -> Union[List[Dict[str, Any]], str]: """ Parse user input into structured tasks using Claude 3. Args: user_input (str): The user's natural language input describing their goals Returns: Union[List[Dict[str, Any]], str]: Either a list of task dictionaries or an error message """ prompt = f""" You are a helpful assistant that turns vague personal goals into clear, actionable tasks. Break this input into tasks with: - task name (key: "task") - category (key: "category") - Choose from: Career, Learning, Personal, Outreach, Health, Finance - priority (key: "priority") - Choose from: High, Medium, Low - optional due date (key: "dueDate") - Use ISO format YYYY-MM-DD if date is mentioned or inferred - notes (key: "notes") - Add relevant context or subtasks Return ONLY a valid JSON array of task objects with the exact keys mentioned above. Each task MUST have at least task, category, and priority fields. Input: \"\"\"{user_input}\"\"\" """ try: response = client.messages.create( model="claude-3-haiku-20240307", max_tokens=1024, temperature=0.4, messages=[ {"role": "user", "content": prompt} ] ) content = response.content[0].text.strip() tasks = json.loads(content) # Validate required fields for task in tasks: if not all(k in task for k in ["task", "category", "priority"]): return "Error: Each task must have task, category, and priority fields" # Validate category and priority values if task["category"] not in ["Career", "Learning", "Personal", "Outreach", "Health", "Finance"]: return f"Error: Invalid category '{task['category']}' in task '{task['task']}'" if task["priority"] not in ["High", "Medium", "Low"]: return f"Error: Invalid priority '{task['priority']}' in task '{task['task']}'" return tasks except anthropic.APIError as e: return f"Claude API Error: {str(e)}" except json.JSONDecodeError: return "Error: Failed to parse Claude's response as JSON" except Exception as e: return f"Unexpected error: {str(e)}"