tt / memory_handler.py
shamimjony1000's picture
Upload 8 files
c82da72 verified
from gtts import gTTS
import io
import gradio as gr
from datetime import datetime, timedelta
import json
class MemoryHandler:
def __init__(self):
self.conversation_history = []
self.max_history = 5 # Keep last 5 interactions
self.context_timeout = timedelta(minutes=2) # Context expires after 2 minutes
self.last_interaction_time = None
self.partial_info = {
'project_number': None,
'project_name': None,
'amount': None,
'reason': None,
'timestamp': None
}
self.confidence_scores = {
'project_number': 0.0,
'project_name': 0.0,
'amount': 0.0,
'reason': 0.0
}
def add_interaction(self, text: str, extracted_info: dict = None) -> None:
"""
Add a new interaction to the conversation history and update partial information
Args:
text: The text from the voice/text input
extracted_info: Dictionary containing extracted request details
"""
current_time = datetime.now()
# Check if we should clear context due to timeout
if self.last_interaction_time and \
(current_time - self.last_interaction_time) > self.context_timeout:
self.clear_partial_info()
# Update conversation history
if text:
# Add timestamp to conversation history
self.conversation_history.append({
'text': text,
'timestamp': current_time.isoformat(),
'extracted_info': extracted_info
})
if len(self.conversation_history) > self.max_history:
self.conversation_history.pop(0)
# Update partial information if provided
if extracted_info:
self._update_partial_info(extracted_info, current_time)
self.last_interaction_time = current_time
def _update_partial_info(self, extracted_info: dict, current_time: datetime) -> None:
"""
Update partial information with confidence scoring
"""
for key in self.partial_info:
if key in extracted_info and extracted_info[key]:
new_value = extracted_info[key]
current_value = self.partial_info[key]
# Update if empty or higher confidence
if (current_value is None or
extracted_info.get(f'{key}_confidence', 0.5) >
self.confidence_scores.get(key, 0)):
self.partial_info[key] = new_value
self.confidence_scores[key] = extracted_info.get(f'{key}_confidence', 0.5)
self.partial_info['timestamp'] = current_time
def get_context(self) -> str:
"""
Get the current conversation context including partial information
"""
# Start with the most recent conversation history
context_parts = []
# Add conversation history with timestamps
for entry in self.conversation_history:
timestamp = datetime.fromisoformat(entry['timestamp']).strftime('%H:%M:%S')
context_parts.append(f"[{timestamp}] {entry['text']}")
context = " ".join(context_parts)
# Add partial information to context if available
partial_context = []
for key, value in self.partial_info.items():
if value and key != 'timestamp':
confidence = self.confidence_scores.get(key, 0)
partial_context.append(f"{key}: {value} (confidence: {confidence:.2f})")
if partial_context:
context += "\nPartial information: " + ", ".join(partial_context)
return context
def get_partial_info(self) -> dict:
"""Get current partial information with confidence scores"""
info = {k: v for k, v in self.partial_info.items()
if k != 'timestamp' and v is not None}
info['confidence_scores'] = self.confidence_scores
return info
def merge_partial_info(self, new_info: dict) -> None:
"""
Merge new information with existing partial info based on confidence scores
"""
for key in self.partial_info:
if key in new_info and new_info[key] is not None:
new_confidence = new_info.get(f'{key}_confidence', 0.5)
if (self.partial_info[key] is None or
new_confidence > self.confidence_scores.get(key, 0)):
self.partial_info[key] = new_info[key]
self.confidence_scores[key] = new_confidence
def clear_partial_info(self) -> None:
"""Clear partial information and confidence scores"""
self.partial_info = {
'project_number': None,
'project_name': None,
'amount': None,
'reason': None,
'timestamp': None
}
self.confidence_scores = {
'project_number': 0.0,
'project_name': 0.0,
'amount': 0.0,
'reason': 0.0
}
def clear_memory(self) -> None:
"""Clear all conversation history and partial information"""
self.conversation_history = []
self.clear_partial_info()
self.last_interaction_time = None
return "Memory cleared!"
def get_missing_fields(self) -> list:
"""Get list of missing required fields with confidence thresholds"""
missing = []
confidence_threshold = 0.5 # Minimum confidence required
for field in ['project_number', 'project_name', 'amount', 'reason']:
if (self.partial_info.get(field) is None or
self.confidence_scores.get(field, 0) < confidence_threshold):
missing.append(field)
return missing
def text_to_speech(self, text: str) -> tuple[str, str]:
"""Convert text to speech and return audio path"""
try:
tts = gTTS(text=text, lang='en')
audio_path = "temp_audio.mp3"
tts.save(audio_path)
return audio_path, None
except Exception as e:
return None, f"Error generating audio: {str(e)}"
def create_confirmation_audio(self, project_number: str, project_name: str,
amount: float, reason: str) -> tuple[str, str]:
"""Create confirmation message audio with confidence information"""
confidence_info = "\n".join([
f"{field}: {self.confidence_scores.get(field, 0):.2f} confidence"
for field in ['project_number', 'project_name', 'amount', 'reason']
])
confirmation_text = (
f"You are going to add request money for project ID: {project_number}, "
f"Project name: {project_name}, request amount: {amount}, "
f"reason: {reason}.\n\nConfidence scores:\n{confidence_info}\n"
f"Are you sure you want to proceed?"
)
return self.text_to_speech(confirmation_text)
def get_prompt_for_missing_info(self) -> str:
"""Generate a prompt for missing information with confidence scores"""
missing = self.get_missing_fields()
if not missing:
return "All required information has been provided with sufficient confidence."
current_info = self.get_partial_info()
prompt = "Current information:\n"
# Show current information with confidence scores
for key, value in current_info.items():
if key != 'confidence_scores' and value is not None:
confidence = self.confidence_scores.get(key, 0)
prompt += f"- {key}: {value} (confidence: {confidence:.2f})\n"
prompt += "\nPlease provide or clarify the following information:\n"
for field in missing:
current_confidence = self.confidence_scores.get(field, 0)
if current_confidence > 0:
prompt += f"- {field} (current confidence: {current_confidence:.2f}, needs improvement)\n"
else:
prompt += f"- {field} (missing)\n"
return prompt
def to_json(self) -> str:
"""Serialize the memory state to JSON"""
return json.dumps({
'conversation_history': self.conversation_history,
'partial_info': self.partial_info,
'confidence_scores': self.confidence_scores,
'last_interaction_time': self.last_interaction_time.isoformat() if self.last_interaction_time else None
})
def from_json(self, json_str: str) -> None:
"""Restore memory state from JSON"""
data = json.loads(json_str)
self.conversation_history = data['conversation_history']
self.partial_info = data['partial_info']
self.confidence_scores = data['confidence_scores']
self.last_interaction_time = (datetime.fromisoformat(data['last_interaction_time'])
if data['last_interaction_time'] else None)