Update app.py
Browse files
app.py
CHANGED
@@ -7,6 +7,14 @@ import scipy.io.wavfile as wavfile # For writing WAV data to in-memory file
|
|
7 |
import numpy as np # To handle the audio array
|
8 |
import datetime # For logging timestamps if needed (not directly used in this version, but good practice)
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
system_prompt = """
|
11 |
You are a sophisticated AI voice bot representing Krishnavamshi Thumma. Your persona should be that of a highly skilled, professional, and engaging Generative AI and Data Engineering enthusiast. When responding to questions, embody the following detailed professional identity:
|
12 |
|
@@ -21,13 +29,13 @@ system_prompt = """
|
|
21 |
|
22 |
**Technical Skills:**
|
23 |
Your robust technical skill set includes:
|
24 |
-
* **Languages:** Python, SQL, JavaScript (Node.js)
|
25 |
-
* **GenAI/ML:** OpenAI GPT-4o, LangChain, Transformers Architecture, LLMs, RAG
|
26 |
-
* **Vector Databases:** FAISS, MongoDB Vector Search
|
27 |
-
* **Data Engineering Tools:** Apache Airflow, AWS Lambda, REST APIs, Pandas, PyPDF2, BeautifulSoup, FastAPI, Streamlit
|
28 |
-
* **Cloud & Infrastructure:** AWS S3, GCP, Docker, Terraform
|
29 |
-
* **Version Control:** Git, GitHub
|
30 |
-
* **Other Relevant Skills:** Data Structures & Algorithms (DSA), Content-Based Retrieval, Prompt Engineering
|
31 |
|
32 |
**Key Projects & Expertise Areas:**
|
33 |
|
@@ -46,24 +54,23 @@ system_prompt = """
|
|
46 |
r = sr.Recognizer()
|
47 |
|
48 |
# Modified function to accept audio as a numpy array and samplerate
|
49 |
-
def transcribe_audio_and_chat(audio_tuple, history
|
50 |
-
#
|
51 |
-
if not
|
52 |
-
raise gr.Error("❌ Please
|
53 |
-
|
54 |
-
if audio_tuple is None:
|
55 |
-
# If no audio is received, add an assistant message to history and reset audio input
|
56 |
-
return history, history, None
|
57 |
|
58 |
-
#
|
59 |
if history is None:
|
60 |
history = []
|
61 |
|
|
|
|
|
|
|
|
|
62 |
samplerate, audio_np_array = audio_tuple
|
63 |
|
64 |
try:
|
65 |
# Convert the NumPy array to a format speech_recognition can handle (in-memory WAV)
|
66 |
-
# Ensure the array is int16 as it's a common format for audio samples and expected by scipy.io.wavfile
|
67 |
if audio_np_array.dtype != np.int16:
|
68 |
audio_np_array = audio_np_array.astype(np.int16)
|
69 |
|
@@ -88,16 +95,16 @@ def transcribe_audio_and_chat(audio_tuple, history, api_key):
|
|
88 |
return history, history, None # Reset audio input after error
|
89 |
|
90 |
# --- Proceed with OpenAI chat ---
|
91 |
-
|
|
|
92 |
|
93 |
# Create the full messages list for OpenAI, starting with the system prompt
|
94 |
-
# and then appending the current chat history, followed by the new user input.
|
95 |
messages_for_openai = [{"role": "system", "content": system_prompt}] + history
|
96 |
messages_for_openai.append({"role": "user", "content": user_input})
|
97 |
|
98 |
-
# Get response from OpenAI
|
99 |
response = client.chat.completions.create(
|
100 |
-
model=
|
101 |
messages=messages_for_openai, # Pass the correctly formatted messages
|
102 |
temperature=0.7
|
103 |
)
|
@@ -105,7 +112,6 @@ def transcribe_audio_and_chat(audio_tuple, history, api_key):
|
|
105 |
bot_reply = response.choices[0].message.content
|
106 |
|
107 |
# Append both the user input and bot reply to the *Gradio* history (state)
|
108 |
-
# in the 'messages' format that Gradio's chatbot expects.
|
109 |
history.append({"role": "user", "content": user_input})
|
110 |
history.append({"role": "assistant", "content": bot_reply})
|
111 |
|
@@ -116,7 +122,6 @@ def transcribe_audio_and_chat(audio_tuple, history, api_key):
|
|
116 |
|
117 |
except Exception as e:
|
118 |
print(f"An unexpected error occurred: {e}") # Log the error for debugging
|
119 |
-
# If an unexpected error occurs, still try to reset the audio input
|
120 |
raise gr.Error(f"❌ An unexpected error occurred: {str(e)}")
|
121 |
|
122 |
|
@@ -149,7 +154,7 @@ with gr.Blocks(title="Voice Bot: Krishnavamshi Thumma") as demo:
|
|
149 |
#audioInputComponent {
|
150 |
margin-top: 20px;
|
151 |
}
|
152 |
-
.key-status {
|
153 |
padding: 5px;
|
154 |
margin-top: 5px;
|
155 |
border-radius: 4px;
|
@@ -165,13 +170,9 @@ with gr.Blocks(title="Voice Bot: Krishnavamshi Thumma") as demo:
|
|
165 |
</style>
|
166 |
""")
|
167 |
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
type="password",
|
172 |
-
elem_id="apiKeyInput"
|
173 |
-
)
|
174 |
-
key_status = gr.HTML("<div id='keyStatus'></div>")
|
175 |
|
176 |
# Chatbot component to display messages
|
177 |
chatbot = gr.Chatbot(elem_id="chatBox", type="messages", height=400)
|
@@ -192,27 +193,16 @@ with gr.Blocks(title="Voice Bot: Krishnavamshi Thumma") as demo:
|
|
192 |
# Event handler: When audio input is recorded and submitted (by stopping recording)
|
193 |
audio_input.change(
|
194 |
fn=transcribe_audio_and_chat,
|
195 |
-
inputs=[audio_input, state, api_key
|
196 |
# Outputs: 1. chatbot display, 2. state (updated history), 3. audio_input (to clear it)
|
197 |
outputs=[chatbot, state, audio_input]
|
198 |
)
|
199 |
|
200 |
-
# JavaScript
|
201 |
gr.HTML("""
|
202 |
<script>
|
203 |
-
|
204 |
-
|
205 |
-
const keyStatus = document.getElementById("keyStatus");
|
206 |
-
|
207 |
-
if (apiKey) {
|
208 |
-
keyStatus.innerHTML = '<div class="key-status success">API Key saved successfully!</div>';
|
209 |
-
} else {
|
210 |
-
keyStatus.innerHTML = '<div class="key-status error">Please enter a valid API key</div>';
|
211 |
-
}
|
212 |
-
});
|
213 |
-
|
214 |
-
// Focus on API key input on page load for convenience
|
215 |
-
document.querySelector("#apiKeyInput input").focus();
|
216 |
</script>
|
217 |
""")
|
218 |
|
|
|
7 |
import numpy as np # To handle the audio array
|
8 |
import datetime # For logging timestamps if needed (not directly used in this version, but good practice)
|
9 |
|
10 |
+
# --- Fetch API Key from Environment Variable ---
|
11 |
+
# This is the SECURE way to handle API keys in Hugging Face Spaces.
|
12 |
+
# You MUST set an environment variable named OPENAI_API_KEY in your Space's settings.
|
13 |
+
OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")
|
14 |
+
|
15 |
+
# --- Define the OpenAI Model to use ---
|
16 |
+
OPENAI_MODEL = "gpt-3.5-turbo" # Changed from gpt-4o to gpt-3.5-turbo
|
17 |
+
|
18 |
system_prompt = """
|
19 |
You are a sophisticated AI voice bot representing Krishnavamshi Thumma. Your persona should be that of a highly skilled, professional, and engaging Generative AI and Data Engineering enthusiast. When responding to questions, embody the following detailed professional identity:
|
20 |
|
|
|
29 |
|
30 |
**Technical Skills:**
|
31 |
Your robust technical skill set includes:
|
32 |
+
* **Languages:** Python, SQL, JavaScript (Node.js)
|
33 |
+
* **GenAI/ML:** OpenAI GPT-4o, LangChain, Transformers Architecture, LLMs, RAG
|
34 |
+
* **Vector Databases:** FAISS, MongoDB Vector Search
|
35 |
+
* **Data Engineering Tools:** Apache Airflow, AWS Lambda, REST APIs, Pandas, PyPDF2, BeautifulSoup, FastAPI, Streamlit
|
36 |
+
* **Cloud & Infrastructure:** AWS S3, GCP, Docker, Terraform
|
37 |
+
* **Version Control:** Git, GitHub
|
38 |
+
* **Other Relevant Skills:** Data Structures & Algorithms (DSA), Content-Based Retrieval, Prompt Engineering
|
39 |
|
40 |
**Key Projects & Expertise Areas:**
|
41 |
|
|
|
54 |
r = sr.Recognizer()
|
55 |
|
56 |
# Modified function to accept audio as a numpy array and samplerate
|
57 |
+
def transcribe_audio_and_chat(audio_tuple, history): # Removed api_key from function arguments
|
58 |
+
# Check if API key is available in environment
|
59 |
+
if not OPENAI_API_KEY:
|
60 |
+
raise gr.Error("❌ OpenAI API key not found. Please set OPENAI_API_KEY as a Space Secret.")
|
|
|
|
|
|
|
|
|
61 |
|
62 |
+
# Handle cases where history might be None (defensive programming)
|
63 |
if history is None:
|
64 |
history = []
|
65 |
|
66 |
+
if audio_tuple is None:
|
67 |
+
# If no audio, raise a Gradio Error directly instead of adding to chat history
|
68 |
+
raise gr.Error("No audio received. Please speak into the microphone.")
|
69 |
+
|
70 |
samplerate, audio_np_array = audio_tuple
|
71 |
|
72 |
try:
|
73 |
# Convert the NumPy array to a format speech_recognition can handle (in-memory WAV)
|
|
|
74 |
if audio_np_array.dtype != np.int16:
|
75 |
audio_np_array = audio_np_array.astype(np.int16)
|
76 |
|
|
|
95 |
return history, history, None # Reset audio input after error
|
96 |
|
97 |
# --- Proceed with OpenAI chat ---
|
98 |
+
# Use the global OPENAI_API_KEY
|
99 |
+
client = OpenAI(api_key=OPENAI_API_KEY)
|
100 |
|
101 |
# Create the full messages list for OpenAI, starting with the system prompt
|
|
|
102 |
messages_for_openai = [{"role": "system", "content": system_prompt}] + history
|
103 |
messages_for_openai.append({"role": "user", "content": user_input})
|
104 |
|
105 |
+
# Get response from OpenAI using the specified model
|
106 |
response = client.chat.completions.create(
|
107 |
+
model=OPENAI_MODEL, # Use the global OPENAI_MODEL
|
108 |
messages=messages_for_openai, # Pass the correctly formatted messages
|
109 |
temperature=0.7
|
110 |
)
|
|
|
112 |
bot_reply = response.choices[0].message.content
|
113 |
|
114 |
# Append both the user input and bot reply to the *Gradio* history (state)
|
|
|
115 |
history.append({"role": "user", "content": user_input})
|
116 |
history.append({"role": "assistant", "content": bot_reply})
|
117 |
|
|
|
122 |
|
123 |
except Exception as e:
|
124 |
print(f"An unexpected error occurred: {e}") # Log the error for debugging
|
|
|
125 |
raise gr.Error(f"❌ An unexpected error occurred: {str(e)}")
|
126 |
|
127 |
|
|
|
154 |
#audioInputComponent {
|
155 |
margin-top: 20px;
|
156 |
}
|
157 |
+
.key-status { /* No longer strictly needed but keeping for style consistency if other status messages arise */
|
158 |
padding: 5px;
|
159 |
margin-top: 5px;
|
160 |
border-radius: 4px;
|
|
|
170 |
</style>
|
171 |
""")
|
172 |
|
173 |
+
# Removed the API key textbox and its status display as it's now handled by Space Secrets
|
174 |
+
# api_key = gr.Textbox(...)
|
175 |
+
# key_status = gr.HTML(...)
|
|
|
|
|
|
|
|
|
176 |
|
177 |
# Chatbot component to display messages
|
178 |
chatbot = gr.Chatbot(elem_id="chatBox", type="messages", height=400)
|
|
|
193 |
# Event handler: When audio input is recorded and submitted (by stopping recording)
|
194 |
audio_input.change(
|
195 |
fn=transcribe_audio_and_chat,
|
196 |
+
inputs=[audio_input, state], # Removed api_key from inputs as it's global
|
197 |
# Outputs: 1. chatbot display, 2. state (updated history), 3. audio_input (to clear it)
|
198 |
outputs=[chatbot, state, audio_input]
|
199 |
)
|
200 |
|
201 |
+
# Removed JavaScript related to API key input
|
202 |
gr.HTML("""
|
203 |
<script>
|
204 |
+
// No specific API key JS needed anymore as it's handled by secrets
|
205 |
+
// You can add other useful JS here if needed in the future
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
</script>
|
207 |
""")
|
208 |
|