onisj commited on
Commit
0f4d69d
Β·
verified Β·
1 Parent(s): 10c21cb
Files changed (1) hide show
  1. Main2.py +195 -128
Main2.py CHANGED
@@ -1,7 +1,6 @@
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,28 +10,23 @@ import uuid
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,6 +38,7 @@ class Character(db.Model):
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,46 +52,38 @@ def app_context():
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,11 +93,17 @@ def add_character(name, description, prompt_template):
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,28 +121,49 @@ def get_existing_characters():
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,11 +173,13 @@ def chat_with_character(character_name, user_input, user_id, chat_id=None):
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,48 +193,50 @@ def speech_to_text(audio_file):
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,59 +246,101 @@ def create_interface():
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,41 +349,48 @@ def create_interface():
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)
 
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
  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
 
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
  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
  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
  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
  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
  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
  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
  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)