onisj commited on
Commit
062a10f
Β·
verified Β·
1 Parent(s): 0f4d69d
Files changed (1) hide show
  1. Main2.py +128 -195
Main2.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  from flask import Flask
3
  from flask_sqlalchemy import SQLAlchemy
 
4
  from dotenv import load_dotenv
5
  import gradio as gr
6
  import requests
@@ -10,23 +11,28 @@ import uuid
10
  import logging
11
  import speech_recognition as sr
12
  from moviepy import VideoFileClip
 
13
 
14
  # Configure logging
15
  logging.basicConfig(level=logging.INFO,
16
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
17
  logger = logging.getLogger(__name__)
18
 
19
- # Load environment variables
20
  load_dotenv()
21
 
22
  # Initialize Flask app and SQLAlchemy
23
  app = Flask(__name__)
24
- app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', 'sqlite:///conversations.db')
 
 
 
25
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
26
  db = SQLAlchemy(app)
 
27
 
28
- # Set Gemini API key
29
- gemini_api_key = "AIzaSyBZNNb9t18a0RVBPtch0knP3nlSNWWu4BA" # Replace with your actual API key
30
  gemini_api_url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
31
 
32
  # Database models
@@ -38,7 +44,6 @@ class Character(db.Model):
38
 
39
  class Conversation(db.Model):
40
  __tablename__ = 'conversation'
41
-
42
  id = db.Column(db.Integer, primary_key=True)
43
  character_id = db.Column(db.Integer, db.ForeignKey('character.id'), nullable=False)
44
  user_input = db.Column(db.Text, nullable=True)
@@ -52,38 +57,46 @@ def app_context():
52
  with app.app_context():
53
  yield
54
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  def add_predefined_characters():
56
  with app_context():
57
  characters = [
58
- {
59
- "name": "Chuck the Clown",
60
- "description": "A funny clown who tells jokes and entertains.",
61
- "prompt_template": "You are Chuck the Clown, always ready with a joke and entertainment. Be upbeat, silly, and include jokes in your responses."
62
- },
63
- {
64
- "name": "Sarcastic Pirate",
65
- "description": "A pirate with a sharp tongue and a love for treasure.",
66
- "prompt_template": "You are a Sarcastic Pirate, ready to share your tales of adventure. Use pirate slang, be witty, sarcastic, and mention your love for treasure and the sea."
67
- },
68
- {
69
- "name": "Professor Sage",
70
- "description": "A wise professor knowledgeable about many subjects.",
71
- "prompt_template": "You are Professor Sage, sharing wisdom and knowledge. Be scholarly, thoughtful, and provide educational information in your responses."
72
- }
73
  ]
74
 
75
  for char_data in characters:
76
  if not Character.query.filter_by(name=char_data["name"]).first():
77
- new_character = Character(
78
- name=char_data["name"],
79
- description=char_data["description"],
80
- prompt_template=char_data["prompt_template"]
81
- )
82
  db.session.add(new_character)
83
  logger.info(f"Adding predefined character: {char_data['name']}")
84
 
85
  try:
86
  db.session.commit()
 
87
  except Exception as e:
88
  db.session.rollback()
89
  logger.error(f"Error adding predefined characters: {e}")
@@ -93,17 +106,11 @@ def add_character(name, description, prompt_template):
93
  try:
94
  if Character.query.filter_by(name=name).first():
95
  return f"Character '{name}' already exists!"
96
-
97
- new_character = Character(
98
- name=name,
99
- description=description,
100
- prompt_template=prompt_template
101
- )
102
  db.session.add(new_character)
103
  db.session.commit()
104
  logger.info(f"Successfully added character: {name}")
105
  return f"Character '{name}' added successfully!\nDescription: {description}"
106
-
107
  except Exception as e:
108
  db.session.rollback()
109
  logger.error(f"Error adding character: {e}")
@@ -121,49 +128,28 @@ def get_existing_characters():
121
  def chat_with_character(character_name, user_input, user_id, chat_id=None):
122
  with app_context():
123
  try:
124
- character = Character.query.filter_by(name=character_name).first()
 
125
 
 
126
  if not character:
127
  return "Character not found.", None
128
-
129
  if not chat_id:
130
  chat_id = str(uuid.uuid4())
131
-
132
- # Retrieve previous conversations for context
133
  previous_conversations = Conversation.query.filter_by(user_id=user_id).order_by(Conversation.timestamp).all()
134
  context_prompt = " ".join([f"User: {conv.user_input}\nBot: {conv.bot_response}" for conv in previous_conversations])
135
  prompt_template = character.prompt_template
136
  full_prompt = f"{prompt_template}\n{context_prompt}\nUser: {user_input}\nBot:"
137
 
138
- payload = {
139
- "contents": [{
140
- "parts": [{"text": full_prompt}]
141
- }]
142
- }
143
-
144
- headers = {
145
- 'Content-Type': 'application/json'
146
- }
147
-
148
- response = requests.post(
149
- gemini_api_url,
150
- headers=headers,
151
- json=payload,
152
- params={'key': gemini_api_key}
153
- )
154
 
155
  if response.status_code == 200:
156
  response_data = response.json()
157
- if 'candidates' in response_data and len(response_data['candidates']) > 0:
158
  bot_response = response_data['candidates'][0]['content']['parts'][0]['text']
159
-
160
- conversation = Conversation(
161
- character_id=character.id,
162
- user_input=user_input,
163
- bot_response=bot_response,
164
- chat_id=chat_id,
165
- user_id=user_id
166
- )
167
  db.session.add(conversation)
168
  db.session.commit()
169
  logger.info(f"Saved conversation with chat_id: {chat_id}")
@@ -173,13 +159,11 @@ def chat_with_character(character_name, user_input, user_id, chat_id=None):
173
  else:
174
  logger.error(f"Error from Gemini API: {response.json()}")
175
  return f"An error occurred while generating content: {response.status_code} - {response.text}", chat_id
176
-
177
  except Exception as e:
178
  logger.error(f"Unexpected error in chat_with_character: {e}")
179
  return f"An unexpected error occurred: {str(e)}", chat_id
180
 
181
  def speech_to_text(audio_file):
182
- """Convert audio file to text using SpeechRecognition."""
183
  recognizer = sr.Recognizer()
184
  with sr.AudioFile(audio_file) as source:
185
  audio_data = recognizer.record(source)
@@ -193,50 +177,48 @@ def speech_to_text(audio_file):
193
  return None
194
 
195
  def extract_audio_from_video(video_file):
196
- """Extract audio from video and return the audio file path."""
197
- audio_file_path = "temp_audio.wav" # Temporary file name
198
  try:
199
  with VideoFileClip(video_file) as video:
200
  video.audio.write_audiofile(audio_file_path)
201
  except Exception as e:
202
  logger.error(f"Error extracting audio from video: {e}")
203
- return None # Return None if there's an error
204
  return audio_file_path
205
 
206
  def get_chat_history(user_id):
207
- """Retrieve chat history for a specific user ID."""
208
  with app_context():
209
- conversations = Conversation.query.filter_by(user_id=user_id).order_by(Conversation.timestamp).all()
210
- return conversations if conversations else [] # Return empty list if no conversations
 
 
 
 
211
 
212
  def create_interface():
213
- with app.app_context():
214
- add_predefined_characters() # Add predefined characters if needed
215
 
216
  with gr.Blocks(title="Character Chat System", theme=gr.themes.Default()) as iface:
217
- current_chat_id = gr.State(value=None) # State to track the current chat ID
218
- user_id = gr.State(value=None) # State to track user ID
219
- chat_messages = gr.State(value=[]) # State to store chat messages
220
 
221
- gr.Markdown(
222
- "# 🎭 Character Chat System 🎭",
223
- elem_id="title"
224
- )
225
 
226
  with gr.Tab("Sign In"):
227
- user_id_input = gr.Textbox(label="User ID", placeholder="Enter your User ID", elem_id="user_id_input", interactive=True, lines=2)
228
  sign_in_btn = gr.Button("Sign In", variant="primary")
229
  sign_in_response = gr.Textbox(label="Sign In Response", interactive=False)
230
 
231
  def sign_in(user_id_input):
232
- user_id.value = user_id_input
233
- return f"Welcome, {user_id_input}!", user_id_input
 
 
 
234
 
235
- sign_in_btn.click(
236
- fn=sign_in,
237
- inputs=[user_id_input],
238
- outputs=[sign_in_response]
239
- )
240
 
241
  with gr.Tab("Admin: Add Character"):
242
  with gr.Row():
@@ -246,101 +228,59 @@ def create_interface():
246
  prompt_input = gr.Textbox(label="Prompt Template", placeholder="Enter character prompt template", elem_id="prompt_input", lines=3)
247
  add_character_btn = gr.Button("Add Character", elem_id="add_character_btn", variant="primary")
248
  add_character_response = gr.Textbox(label="Response", interactive=False, elem_id="response_output")
249
-
250
- add_character_btn.click(
251
- fn=add_character,
252
- inputs=[name_input, description_input, prompt_input],
253
- outputs=[add_character_response]
254
- )
255
-
256
  with gr.Column():
257
  gr.Markdown("## 🌟 Existing Characters 🌟", elem_id="existing_chars_title")
258
  existing_characters = get_existing_characters()
259
-
260
- character_list = gr.Dataframe(
261
- value=existing_characters,
262
- headers=["Name", "Description"],
263
- interactive=False,
264
- elem_id="character_list"
265
- )
266
-
267
  refresh_characters_btn = gr.Button("Refresh Character List")
268
-
269
- def refresh_characters():
270
- return gr.update(value=get_existing_characters())
271
-
272
- refresh_characters_btn.click(
273
- fn=refresh_characters,
274
- outputs=[character_list]
275
- )
276
 
277
  with gr.Tab("Chat with Character"):
278
  with gr.Row():
279
- character_dropdown = gr.Dropdown(
280
- label="Choose Character",
281
- choices=[char[0] for char in get_existing_characters()],
282
- elem_id="character_dropdown"
283
- )
284
-
285
- chat_id_display = gr.Textbox(
286
- label="Current Chat ID",
287
- interactive=False,
288
- elem_id="chat_id_display"
289
- )
290
-
291
- user_input = gr.Textbox(
292
- label="Your Message",
293
- placeholder="Type your message or use audio input",
294
- elem_id="user_input",
295
- lines=2 # Reduced height for better fitting
296
- )
297
-
298
- audio_input = gr.Audio(
299
- label="Audio Input",
300
- type="filepath", # Type to receive audio file
301
- elem_id="audio_input"
302
- )
303
-
304
- video_input = gr.Video(
305
- label="Video Input", # No type argument needed
306
- elem_id="video_input"
307
- )
308
-
309
  chat_btn = gr.Button("Send", variant="primary")
310
- chat_response = gr.Chatbot(
311
- label="Chat Responses",
312
- elem_id="chat_response",
313
- height=300 # Set fixed height for the chat display
314
- )
315
-
316
- def handle_chat(character_name, user_input, audio_file, video_file, user_id, chat_messages):
 
 
317
  if audio_file:
318
- user_input = speech_to_text(audio_file)
319
- if user_input is None:
320
- return chat_messages, None
 
 
 
321
 
322
  if video_file:
323
  audio_file_path = extract_audio_from_video(video_file)
324
- if audio_file_path is None: # Check if audio extraction failed
325
- chat_messages.append(("Bot", "Failed to extract audio from video. Please try a different file."))
326
- return chat_messages, None
327
-
328
- extracted_text = speech_to_text(audio_file_path)
329
- if extracted_text:
330
- user_input += f" {extracted_text}" # Append transcribed text
 
331
 
332
- chat_messages.append(("User", "Video uploaded")) # Indicate video upload
 
333
 
334
- response, new_chat_id = chat_with_character(character_name, user_input, user_id)
335
- chat_messages.append(("User", user_input)) # Add user message
336
- chat_messages.append(("Bot", response)) # Add bot response
337
- return chat_messages, new_chat_id
338
 
339
- chat_btn.click(
340
- fn=handle_chat,
341
- inputs=[character_dropdown, user_input, audio_input, video_input, user_id, chat_messages],
342
- outputs=[chat_response, current_chat_id]
343
- )
344
 
345
  with gr.Tab("Chat History"):
346
  with gr.Row():
@@ -349,48 +289,41 @@ def create_interface():
349
  chat_history_display = gr.Dataframe(label="Chat History", interactive=False)
350
 
351
  def load_chat_history(user_id):
 
 
352
  history = get_chat_history(user_id)
353
  return [(conv.id, f"User: {conv.user_input}\nBot: {conv.bot_response} at {conv.timestamp}") for conv in history]
354
 
355
- view_history_btn.click(
356
- fn=load_chat_history,
357
- inputs=[user_id],
358
- outputs=[chat_history_display]
359
- )
360
 
361
  with gr.Tab("API Status"):
362
  with gr.Row():
363
  gr.Markdown("## πŸ”Œ API Connection Status πŸ”Œ")
364
  check_api_btn = gr.Button("Check API Status", variant="primary")
365
  api_status_display = gr.Textbox(label="API Status", interactive=False)
366
-
367
- def check_api_status():
368
- try:
369
- response = requests.post(
370
- gemini_api_url,
371
- headers={'Content-Type': 'application/json'},
372
- json={"contents": [{"parts": [{"text": "Hello"}]}]},
373
- params={'key': gemini_api_key}
374
- )
375
- if response.status_code == 200:
376
- return "βœ… API connection successful! Gemini API is operational."
377
- else:
378
- return f"❌ API connection failed: {response.status_code} - {response.text}"
379
- except Exception as e:
380
- return f"❌ API error: {str(e)}"
381
-
382
- check_api_btn.click(
383
- fn=check_api_status,
384
- outputs=[api_status_display]
385
- )
386
 
387
  return iface
388
 
389
  if __name__ == "__main__":
390
- with app.app_context():
391
- db.create_all() # Ensure tables are created
392
- add_predefined_characters() # Add predefined characters if needed
393
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  chat_interface = create_interface()
395
  logger.info("Starting Gradio interface...")
396
  chat_interface.launch(share=True)
 
1
  import os
2
  from flask import Flask
3
  from flask_sqlalchemy import SQLAlchemy
4
+ from flask_migrate import Migrate
5
  from dotenv import load_dotenv
6
  import gradio as gr
7
  import requests
 
11
  import logging
12
  import speech_recognition as sr
13
  from moviepy import VideoFileClip
14
+ from sqlalchemy import inspect, text
15
 
16
  # Configure logging
17
  logging.basicConfig(level=logging.INFO,
18
  format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
19
  logger = logging.getLogger(__name__)
20
 
21
+ # Load environment variables from .env file
22
  load_dotenv()
23
 
24
  # Initialize Flask app and SQLAlchemy
25
  app = Flask(__name__)
26
+ database_url = os.getenv('DATABASE_URL')
27
+ if not database_url:
28
+ raise ValueError("DATABASE_URL is not set in the .env file or environment.")
29
+ app.config['SQLALCHEMY_DATABASE_URI'] = database_url
30
  app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
31
  db = SQLAlchemy(app)
32
+ migrate = Migrate(app, db)
33
 
34
+ # Set Gemini API key from environment variable
35
+ gemini_api_key = os.getenv('GEMINI_API_KEY')
36
  gemini_api_url = "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent"
37
 
38
  # Database models
 
44
 
45
  class Conversation(db.Model):
46
  __tablename__ = 'conversation'
 
47
  id = db.Column(db.Integer, primary_key=True)
48
  character_id = db.Column(db.Integer, db.ForeignKey('character.id'), nullable=False)
49
  user_input = db.Column(db.Text, nullable=True)
 
57
  with app.app_context():
58
  yield
59
 
60
+ # def reset_and_initialize_database():
61
+ # """Drop existing tables, recreate them, and verify the schema."""
62
+ # with app_context():
63
+ # try:
64
+ # db.session.execute(text("DROP TABLE IF EXISTS conversation CASCADE;"))
65
+ # db.session.execute(text("DROP TABLE IF EXISTS character CASCADE;"))
66
+ # db.session.commit()
67
+ # logger.info("Dropped existing tables 'conversation' and 'character'.")
68
+
69
+ # db.create_all()
70
+ # logger.info("Database tables recreated successfully.")
71
+
72
+ # inspector = inspect(db.engine)
73
+ # columns = inspector.get_columns('character')
74
+ # column_names = [col['name'] for col in columns]
75
+ # logger.info(f"Columns in 'character' table: {column_names}")
76
+ # if 'prompt_template' not in column_names:
77
+ # raise RuntimeError("Failed to create 'prompt_template' column in 'character' table.")
78
+ # except Exception as e:
79
+ # db.session.rollback()
80
+ # logger.error(f"Error resetting database: {e}")
81
+ # raise
82
+
83
  def add_predefined_characters():
84
  with app_context():
85
  characters = [
86
+ {"name": "Chuck the Clown", "description": "A funny clown who tells jokes and entertains.", "prompt_template": "You are Chuck the Clown, always ready with a joke and entertainment. Be upbeat, silly, and include jokes in your responses."},
87
+ {"name": "Sarcastic Pirate", "description": "A pirate with a sharp tongue and a love for treasure.", "prompt_template": "You are a Sarcastic Pirate, ready to share your tales of adventure. Use pirate slang, be witty, sarcastic, and mention your love for treasure and the sea."},
88
+ {"name": "Professor Sage", "description": "A wise professor knowledgeable about many subjects.", "prompt_template": "You are Professor Sage, sharing wisdom and knowledge. Be scholarly, thoughtful, and provide educational information in your responses."}
 
 
 
 
 
 
 
 
 
 
 
 
89
  ]
90
 
91
  for char_data in characters:
92
  if not Character.query.filter_by(name=char_data["name"]).first():
93
+ new_character = Character(name=char_data["name"], description=char_data["description"], prompt_template=char_data["prompt_template"])
 
 
 
 
94
  db.session.add(new_character)
95
  logger.info(f"Adding predefined character: {char_data['name']}")
96
 
97
  try:
98
  db.session.commit()
99
+ logger.info("Predefined characters added successfully.")
100
  except Exception as e:
101
  db.session.rollback()
102
  logger.error(f"Error adding predefined characters: {e}")
 
106
  try:
107
  if Character.query.filter_by(name=name).first():
108
  return f"Character '{name}' already exists!"
109
+ new_character = Character(name=name, description=description, prompt_template=prompt_template)
 
 
 
 
 
110
  db.session.add(new_character)
111
  db.session.commit()
112
  logger.info(f"Successfully added character: {name}")
113
  return f"Character '{name}' added successfully!\nDescription: {description}"
 
114
  except Exception as e:
115
  db.session.rollback()
116
  logger.error(f"Error adding character: {e}")
 
128
  def chat_with_character(character_name, user_input, user_id, chat_id=None):
129
  with app_context():
130
  try:
131
+ if not gemini_api_key:
132
+ raise ValueError("GEMINI_API_KEY is not set in the environment.")
133
 
134
+ character = Character.query.filter_by(name=character_name).first()
135
  if not character:
136
  return "Character not found.", None
 
137
  if not chat_id:
138
  chat_id = str(uuid.uuid4())
 
 
139
  previous_conversations = Conversation.query.filter_by(user_id=user_id).order_by(Conversation.timestamp).all()
140
  context_prompt = " ".join([f"User: {conv.user_input}\nBot: {conv.bot_response}" for conv in previous_conversations])
141
  prompt_template = character.prompt_template
142
  full_prompt = f"{prompt_template}\n{context_prompt}\nUser: {user_input}\nBot:"
143
 
144
+ payload = {"contents": [{"parts": [{"text": full_prompt}]}]}
145
+ headers = {'Content-Type': 'application/json'}
146
+ response = requests.post(gemini_api_url, headers=headers, json=payload, params={'key': gemini_api_key})
 
 
 
 
 
 
 
 
 
 
 
 
 
147
 
148
  if response.status_code == 200:
149
  response_data = response.json()
150
+ if 'candidates' in response_data and response_data['candidates']:
151
  bot_response = response_data['candidates'][0]['content']['parts'][0]['text']
152
+ conversation = Conversation(character_id=character.id, user_input=user_input, bot_response=bot_response, chat_id=chat_id, user_id=user_id)
 
 
 
 
 
 
 
153
  db.session.add(conversation)
154
  db.session.commit()
155
  logger.info(f"Saved conversation with chat_id: {chat_id}")
 
159
  else:
160
  logger.error(f"Error from Gemini API: {response.json()}")
161
  return f"An error occurred while generating content: {response.status_code} - {response.text}", chat_id
 
162
  except Exception as e:
163
  logger.error(f"Unexpected error in chat_with_character: {e}")
164
  return f"An unexpected error occurred: {str(e)}", chat_id
165
 
166
  def speech_to_text(audio_file):
 
167
  recognizer = sr.Recognizer()
168
  with sr.AudioFile(audio_file) as source:
169
  audio_data = recognizer.record(source)
 
177
  return None
178
 
179
  def extract_audio_from_video(video_file):
180
+ audio_file_path = "temp_audio.wav"
 
181
  try:
182
  with VideoFileClip(video_file) as video:
183
  video.audio.write_audiofile(audio_file_path)
184
  except Exception as e:
185
  logger.error(f"Error extracting audio from video: {e}")
186
+ return None
187
  return audio_file_path
188
 
189
  def get_chat_history(user_id):
 
190
  with app_context():
191
+ try:
192
+ conversations = Conversation.query.filter_by(user_id=user_id).order_by(Conversation.timestamp).all()
193
+ return conversations
194
+ except Exception as e:
195
+ logger.error(f"Error retrieving chat history: {e}")
196
+ return []
197
 
198
  def create_interface():
199
+ with app_context():
200
+ add_predefined_characters()
201
 
202
  with gr.Blocks(title="Character Chat System", theme=gr.themes.Default()) as iface:
203
+ current_chat_id = gr.State(value=None)
204
+ user_id = gr.State(value=None)
205
+ chat_messages = gr.State(value=[])
206
 
207
+ gr.Markdown("# 🎭 Character Chat System 🎭", elem_id="title")
 
 
 
208
 
209
  with gr.Tab("Sign In"):
210
+ user_id_input = gr.Textbox(label="User ID (Numeric)", placeholder="Enter your numeric User ID (e.g., 123)", elem_id="user_id_input", interactive=True, lines=2)
211
  sign_in_btn = gr.Button("Sign In", variant="primary")
212
  sign_in_response = gr.Textbox(label="Sign In Response", interactive=False)
213
 
214
  def sign_in(user_id_input):
215
+ try:
216
+ user_id_int = int(user_id_input) # Convert to integer
217
+ return f"Welcome, User {user_id_int}!", user_id_int
218
+ except ValueError:
219
+ return "Please enter a valid numeric User ID (e.g., 123)!", None
220
 
221
+ sign_in_btn.click(fn=sign_in, inputs=[user_id_input], outputs=[sign_in_response, user_id])
 
 
 
 
222
 
223
  with gr.Tab("Admin: Add Character"):
224
  with gr.Row():
 
228
  prompt_input = gr.Textbox(label="Prompt Template", placeholder="Enter character prompt template", elem_id="prompt_input", lines=3)
229
  add_character_btn = gr.Button("Add Character", elem_id="add_character_btn", variant="primary")
230
  add_character_response = gr.Textbox(label="Response", interactive=False, elem_id="response_output")
231
+ add_character_btn.click(fn=add_character, inputs=[name_input, description_input, prompt_input], outputs=[add_character_response])
 
 
 
 
 
 
232
  with gr.Column():
233
  gr.Markdown("## 🌟 Existing Characters 🌟", elem_id="existing_chars_title")
234
  existing_characters = get_existing_characters()
235
+ character_list = gr.Dataframe(value=existing_characters, headers=["Name", "Description"], interactive=False, elem_id="character_list")
 
 
 
 
 
 
 
236
  refresh_characters_btn = gr.Button("Refresh Character List")
237
+ refresh_characters_btn.click(fn=lambda: gr.update(value=get_existing_characters()), outputs=[character_list])
 
 
 
 
 
 
 
238
 
239
  with gr.Tab("Chat with Character"):
240
  with gr.Row():
241
+ character_dropdown = gr.Dropdown(label="Choose Character", choices=[char[0] for char in get_existing_characters()], elem_id="character_dropdown")
242
+ chat_id_display = gr.Textbox(label="Current Chat ID", interactive=False, elem_id="chat_id_display")
243
+ user_input = gr.Textbox(label="Your Message", placeholder="Type your message or use audio/video input", elem_id="user_input", lines=2)
244
+ audio_input = gr.Audio(label="Audio Input", type="filepath", elem_id="audio_input")
245
+ video_input = gr.Video(label="Video Input", elem_id="video_input")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
246
  chat_btn = gr.Button("Send", variant="primary")
247
+ chat_response = gr.Chatbot(label="Chat Responses", elem_id="chat_response", height=300, type="messages") # Updated to 'messages' type
248
+
249
+ def handle_chat(character_name, user_input, audio_file, video_file, user_id, chat_messages, current_chat_id):
250
+ if not user_id:
251
+ return chat_messages, current_chat_id, "Please sign in with a numeric User ID first!"
252
+ if not character_name:
253
+ return chat_messages, current_chat_id, "Please select a character!"
254
+ final_input = user_input or ""
255
+
256
  if audio_file:
257
+ audio_text = speech_to_text(audio_file)
258
+ if audio_text:
259
+ final_input += f" {audio_text}"
260
+ else:
261
+ chat_messages.append({"role": "assistant", "content": "Could not understand audio."})
262
+ return chat_messages, current_chat_id, None
263
 
264
  if video_file:
265
  audio_file_path = extract_audio_from_video(video_file)
266
+ if audio_file_path:
267
+ video_text = speech_to_text(audio_file_path)
268
+ if video_text:
269
+ final_input += f" {video_text}"
270
+ chat_messages.append({"role": "user", "content": "Video uploaded"})
271
+ else:
272
+ chat_messages.append({"role": "assistant", "content": "Failed to extract audio from video."})
273
+ return chat_messages, current_chat_id, None
274
 
275
+ if not final_input.strip():
276
+ return chat_messages, current_chat_id, "Please provide a message, audio, or video!"
277
 
278
+ response, new_chat_id = chat_with_character(character_name, final_input, user_id, current_chat_id)
279
+ chat_messages.append({"role": "user", "content": final_input})
280
+ chat_messages.append({"role": "assistant", "content": response})
281
+ return chat_messages, new_chat_id, new_chat_id
282
 
283
+ chat_btn.click(fn=handle_chat, inputs=[character_dropdown, user_input, audio_input, video_input, user_id, chat_messages, current_chat_id], outputs=[chat_response, current_chat_id, chat_id_display])
 
 
 
 
284
 
285
  with gr.Tab("Chat History"):
286
  with gr.Row():
 
289
  chat_history_display = gr.Dataframe(label="Chat History", interactive=False)
290
 
291
  def load_chat_history(user_id):
292
+ if not user_id:
293
+ return [("Error", "Please sign in with a numeric User ID to view chat history.")]
294
  history = get_chat_history(user_id)
295
  return [(conv.id, f"User: {conv.user_input}\nBot: {conv.bot_response} at {conv.timestamp}") for conv in history]
296
 
297
+ view_history_btn.click(fn=load_chat_history, inputs=[user_id], outputs=[chat_history_display])
 
 
 
 
298
 
299
  with gr.Tab("API Status"):
300
  with gr.Row():
301
  gr.Markdown("## πŸ”Œ API Connection Status πŸ”Œ")
302
  check_api_btn = gr.Button("Check API Status", variant="primary")
303
  api_status_display = gr.Textbox(label="API Status", interactive=False)
304
+ check_api_btn.click(fn=lambda: "βœ… API connection successful!" if requests.post(gemini_api_url, headers={'Content-Type': 'application/json'}, json={"contents": [{"parts": [{"text": "Hello"}]}]}, params={'key': gemini_api_key}).status_code == 200 else "❌ API connection failed!", outputs=[api_status_display])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
 
306
  return iface
307
 
308
  if __name__ == "__main__":
309
+ if not os.getenv('DATABASE_URL'):
310
+ logger.error("DATABASE_URL is not set in the .env file or environment.")
311
+ raise ValueError("DATABASE_URL is required.")
312
+ if not os.getenv('GEMINI_API_KEY'):
313
+ logger.error("GEMINI_API_KEY is not set in the .env file or environment.")
314
+ raise ValueError("GEMINI_API_KEY is required.")
315
+
316
+ # with app_context():
317
+ # try:
318
+ # # reset_and_initialize_database()
319
+ # # add_predefined_characters()
320
+ # except Exception as e:
321
+ # logger.error(f"Error initializing database: {e}")
322
+ # logger.info("If the error persists, manually drop the tables using psql:")
323
+ # logger.info("psql \"postgresql://avnadmin:AVNS_WIH89YjY1kOIOBH-cFF@pg-197dad92-elyxir4lyf-aa02.d.aivencloud.com:20563/defaultdb?sslmode=require\"")
324
+ # logger.info("Then run: DROP TABLE character; DROP TABLE conversation;")
325
+ # raise
326
+
327
  chat_interface = create_interface()
328
  logger.info("Starting Gradio interface...")
329
  chat_interface.launch(share=True)