-
Notifications
You must be signed in to change notification settings - Fork 0
/
inputHandler.py
146 lines (116 loc) Β· 4.76 KB
/
inputHandler.py
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
import os
from typing import Dict, Any
from datetime import datetime
from openai import OpenAI
from dataclasses import dataclass
@dataclass
class ProcessedActivity:
"""Data class for processed activity information"""
time: str
activity: str
sentiment: str = "neutral"
duration: int = 0 # in minutes
class InputHandler:
def __init__(self):
self.client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
self.system_prompt = """You are an AI assistant specialized in processing daily activity logs.
Your task is to extract structured information about activities from natural language input.
For each activity mentioned, identify:
1. The time it occurred (in HH:MM format)
2. The activity description
3. Any mentioned duration
4. The sentiment/mood (if mentioned)
Format your response as a JSON array with objects containing:
{
"time": "HH:MM",
"activity": "description",
"duration": minutes_as_integer,
"sentiment": "positive/neutral/negative"
}
Example input: "I woke up at 6:30, had a great breakfast until 7:15, then read for 45 minutes"
Example response:
[
{"time": "06:30", "activity": "wake up", "duration": 0, "sentiment": "neutral"},
{"time": "06:30", "activity": "breakfast", "duration": 45, "sentiment": "positive"},
{"time": "07:15", "activity": "reading", "duration": 45, "sentiment": "neutral"}
]
Important rules:
- Always use 24-hour time format
- If duration isn't mentioned, set it to 0
- If sentiment isn't clear, use "neutral"
- Keep activity descriptions concise but clear
- Infer end times when possible
- Include all mentioned activities"""
async def transcribe_audio(self, file_path: str) -> str:
"""Transcribe audio file to text"""
try:
with open(file_path, "rb") as audio_file:
transcript = self.client.audio.transcriptions.create(
model="whisper-1",
file=audio_file,
)
return transcript.text
except Exception as e:
raise Exception(f"Error transcribing audio: {str(e)}")
async def process_message(self, text: str) -> list[ProcessedActivity]:
"""Process text message and extract structured activity data"""
try:
response = self.client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": text}
],
temperature=0.7,
max_tokens=500
)
# Parse the JSON response into ProcessedActivity objects
activities_data = eval(response.choices[0].message.content)
activities = [
ProcessedActivity(
time=activity["time"],
activity=activity["activity"],
sentiment=activity["sentiment"],
duration=activity["duration"]
)
for activity in activities_data
]
return activities
except Exception as e:
raise Exception(f"Error processing message: {str(e)}")
async def handle_voice_message(self, file_path: str) -> list[ProcessedActivity]:
"""Handle voice message from start to finish"""
try:
# First transcribe
transcript = await self.transcribe_audio(file_path)
# Then process
activities = await self.process_message(transcript)
return activities
except Exception as e:
raise Exception(f"Error handling voice message: {str(e)}")
def format_activities_for_display(self, activities: list[ProcessedActivity]) -> str:
"""Format processed activities into a readable message"""
if not activities:
return "No activities found in the message."
message = "π Here's your activity log:\n\n"
for activity in activities:
# Add emoji based on sentiment
sentiment_emoji = {
"positive": "π",
"neutral": "π",
"negative": "π"
}.get(activity.sentiment, "π")
# Format duration if present
duration_text = f" ({activity.duration} mins)" if activity.duration > 0 else ""
message += f"β° {activity.time} - {activity.activity}{duration_text} {sentiment_emoji}\n"
return message
# Usage example:
'''
handler = InputHandler()
# For voice messages:
activities = await handler.handle_voice_message("path_to_audio.ogg")
# For text messages:
activities = await handler.process_message("I woke up at 6:30 and had a great breakfast")
# Format for display:
formatted_message = handler.format_activities_for_display(activities)
'''