File size: 2,728 Bytes
de5b666
 
 
efe51c1
de5b666
 
 
 
efe51c1
 
 
 
de5b666
 
efe51c1
 
 
 
 
 
 
 
 
 
de5b666
 
 
 
efe51c1
 
 
 
 
de5b666
efe51c1
 
de5b666
 
 
 
efe51c1
 
 
 
 
 
 
 
 
 
 
 
de5b666
efe51c1
 
 
 
 
 
 
 
 
 
 
de5b666
efe51c1
 
 
de5b666
efe51c1
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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)}"