iajitpanday commited on
Commit
fba9de8
·
verified ·
1 Parent(s): de01ccf

Create utils.py

Browse files
Files changed (1) hide show
  1. utils.py +176 -0
utils.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Utility functions for the AI call assistant system.
3
+ """
4
+
5
+ import os
6
+ import requests
7
+ import json
8
+ import random
9
+ import tempfile
10
+ import logging
11
+ from pydub import AudioSegment
12
+ import io
13
+ import base64
14
+ from transformers import pipeline
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+ # Initialize HF API token (get this from your HF account)
19
+ HF_API_TOKEN = os.environ.get("HF_API_TOKEN", "")
20
+
21
+ # Initialize intent classifier
22
+ try:
23
+ intent_classifier = pipeline(
24
+ "zero-shot-classification",
25
+ model="facebook/bart-large-mnli",
26
+ )
27
+ except Exception as e:
28
+ logger.error(f"Error loading intent classifier: {e}")
29
+ intent_classifier = None
30
+
31
+ # Possible intents
32
+ POSSIBLE_INTENTS = [
33
+ "product_inquiry",
34
+ "technical_support",
35
+ "billing_question",
36
+ "general_information",
37
+ "appointment_scheduling",
38
+ "complaint",
39
+ "other"
40
+ ]
41
+
42
+ # Fallback responses
43
+ FALLBACK_RESPONSES = [
44
+ "I apologize, but I didn't quite understand that. Could you please repeat your question?",
45
+ "Thank you for your call. I'll make sure someone gets back to you with the information you need.",
46
+ "I'm having trouble processing your request. Let me transfer your information to our team who will get back to you shortly.",
47
+ "I've recorded your message and will have someone contact you as soon as possible.",
48
+ "Thank you for reaching out. I'll make sure your inquiry is addressed by the appropriate team member."
49
+ ]
50
+
51
+ def transcribe_audio(audio_url):
52
+ """
53
+ Transcribe audio using OpenAI Whisper model from Hugging Face
54
+ """
55
+ try:
56
+ # Download audio from Twilio URL
57
+ response = requests.get(audio_url)
58
+ if response.status_code != 200:
59
+ logger.error(f"Failed to download audio from {audio_url}")
60
+ return None
61
+
62
+ audio_content = response.content
63
+
64
+ # Convert to format compatible with Whisper
65
+ audio = AudioSegment.from_file(io.BytesIO(audio_content))
66
+ audio = audio.set_channels(1).set_frame_rate(16000)
67
+
68
+ # Save temporarily
69
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_audio:
70
+ temp_filename = temp_audio.name
71
+ audio.export(temp_filename, format="wav")
72
+
73
+ # Use Hugging Face Whisper API
74
+ API_URL = "https://api-inference.huggingface.co/models/openai/whisper-large-v3"
75
+ headers = {"Authorization": f"Bearer {HF_API_TOKEN}"}
76
+
77
+ with open(temp_filename, "rb") as f:
78
+ audio_data = f.read()
79
+
80
+ response = requests.post(API_URL, headers=headers, data=audio_data)
81
+ os.unlink(temp_filename) # Clean up temp file
82
+
83
+ if response.status_code == 200:
84
+ return response.json().get("text", "")
85
+ else:
86
+ logger.error(f"Error from Whisper API: {response.text}")
87
+ return None
88
+
89
+ except Exception as e:
90
+ logger.error(f"Error transcribing audio: {e}")
91
+ return None
92
+
93
+ def classify_intent(text):
94
+ """Classify the intent of the user's message"""
95
+ if not text or not intent_classifier:
96
+ return "other", 0.0
97
+
98
+ try:
99
+ # Use zero-shot classification to determine intent
100
+ results = intent_classifier(
101
+ text,
102
+ candidate_labels=POSSIBLE_INTENTS,
103
+ hypothesis_template="This is a {} request."
104
+ )
105
+
106
+ # Get top intent and confidence
107
+ top_intent = results["labels"][0]
108
+ confidence = results["scores"][0]
109
+
110
+ return top_intent, confidence
111
+
112
+ except Exception as e:
113
+ logger.error(f"Error classifying intent: {e}")
114
+ return "other", 0.0
115
+
116
+ def get_rag_response(query, intent, hf_space_url):
117
+ """Get response using the RAG system via Hugging Face Spaces"""
118
+ try:
119
+ # Prepare data for the Hugging Face Space
120
+ api_url = f"{hf_space_url}/api/predict"
121
+ payload = {
122
+ "data": [
123
+ query,
124
+ intent
125
+ ]
126
+ }
127
+
128
+ # Check if we should use API token
129
+ headers = {}
130
+ if HF_API_TOKEN:
131
+ headers["Authorization"] = f"Bearer {HF_API_TOKEN}"
132
+
133
+ # Call the Hugging Face Space
134
+ response = requests.post(api_url, json=payload, headers=headers)
135
+
136
+ if response.status_code == 200:
137
+ result = response.json()
138
+ # Extract the response text from the result
139
+ # Structure will depend on your Space's output format
140
+ response_text = result.get("data", ["I'm sorry, I couldn't process that request."])[0]
141
+ return response_text
142
+ else:
143
+ logger.error(f"Error from HF Space: {response.status_code} - {response.text}")
144
+ return get_fallback_response()
145
+
146
+ except Exception as e:
147
+ logger.error(f"Error getting RAG response: {e}")
148
+ return get_fallback_response()
149
+
150
+ def text_to_speech(text):
151
+ """Convert text response to speech using Hugging Face TTS model"""
152
+ if not text:
153
+ return None
154
+
155
+ try:
156
+ API_URL = "https://api-inference.huggingface.co/models/espnet/kan-bayashi_ljspeech_vits"
157
+ headers = {"Authorization": f"Bearer {HF_API_TOKEN}"}
158
+
159
+ payload = {"inputs": text}
160
+ response = requests.post(API_URL, headers=headers, json=payload)
161
+
162
+ if response.status_code == 200:
163
+ # Return audio content in base64 for Twilio
164
+ audio_content = base64.b64encode(response.content).decode("utf-8")
165
+ return audio_content
166
+ else:
167
+ logger.error(f"Error from TTS API: {response.text}")
168
+ return None
169
+
170
+ except Exception as e:
171
+ logger.error(f"Error in text-to-speech: {e}")
172
+ return None
173
+
174
+ def get_fallback_response():
175
+ """Return a fallback response"""
176
+ return random.choice(FALLBACK_RESPONSES)